Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I update from Task the UI Thread?

I have a task that performing some heavy work. I need to path it's result to LogContent

Task<Tuple<SupportedComunicationFormats, List<Tuple<TimeSpan, string>>>>.Factory
    .StartNew(() => DoWork(dlg.FileName))
    .ContinueWith(obj => LogContent = obj.Result);

This is the property:

public Tuple<SupportedComunicationFormats, List<Tuple<TimeSpan, string>>> LogContent
{
    get { return _logContent; }
    private set
    {
        _logContent = value;
        if (_logContent != null)
        {
            string entry = string.Format("Recognized {0} log file",_logContent.Item1);
            _traceEntryQueue.AddEntry(Origin.Internal, entry);
        }
    }
}

Problem is that _traceEntryQueue is data bound to UI, and of cause I will have exception on code like this.

So, my question is how to make it work correctly?

like image 374
Night Walker Avatar asked Jan 31 '13 06:01

Night Walker


People also ask

Can we update UI from thread?

Worker threads However, note that you cannot update the UI from any thread other than the UI thread or the "main" thread. To fix this problem, Android offers several ways to access the UI thread from other threads. Here is a list of methods that can help: Activity.

What are different ways of updating UI from background thread?

In this case, to update the UI from a background thread, you can create a handler attached to the UI thread, and then post an action as a Runnable : Handler handler = new Handler(Looper. getMainLooper()); handler. post(new Runnable() { @Override public void run() { // update the ui from here } });

How do you handle the UI update from multiple threads?

1) Have each thread set a "DataUpdated" flag when new data is available, and have the UI periodically check for new data. 2) Create each thread with a callback to a UI Update(...) method to be called when new data becomes available.

Which method is used to set the update of UI?

Android Thread Updating the UI from a Background Thread The solution is to use the runOnUiThread() method, as it allows you to initiate code execution on the UI thread from a background Thread.


1 Answers

Here is a good article: Parallel Programming: Task Schedulers and Synchronization Context.

Take a look at Task.ContinueWith() method.

Example:

var context = TaskScheduler.FromCurrentSynchronizationContext();
var task = new Task<TResult>(() =>
    {
        TResult r = ...;
        return r;
    });

task.ContinueWith(t =>
    {
        // Update UI (and UI-related data) here: success status.
        // t.Result contains the result.
    },
    CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, context);

task.ContinueWith(t =>
    {
        AggregateException aggregateException = t.Exception;
        aggregateException.Handle(exception => true);
        // Update UI (and UI-related data) here: failed status.
        // t.Exception contains the occured exception.
    },
    CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, context);

task.Start();

Since .NET 4.5 supports async/await keywords (see also Task.Run vs Task.Factory.StartNew):

try
{
    var result = await Task.Run(() => GetResult());
    // Update UI: success.
    // Use the result.
}
catch (Exception ex)
{
    // Update UI: fail.
    // Use the exception.
}
like image 102
Sergey Vyacheslavovich Brunov Avatar answered Sep 26 '22 17:09

Sergey Vyacheslavovich Brunov