Simple Async operation with Continuation scenario

2019-08-16 12:56发布

I have a really simple operation on a WPF app in order to try out async operations. Here is my complete code:

static int GetPrimes() {

    var query =
        from n in Enumerable.Range(3, 5000000).AsParallel()
        where Enumerable.Range(2, (int)Math.Sqrt(n)).All(i => n % i > 0)
        select n;

    return query.Count();
}

private void button1_Click(object sender, RoutedEventArgs e) {

    Task<int> task = Task.Factory.StartNew(
        () => GetPrimes(),
        TaskCreationOptions.LongRunning
    );

    task.ContinueWith(x => {
        label1.Content = task.Result; 
    });
}

As you see, when I push the button it does some stuff and when it finishes it needs to push the result to a label but it doesn't do that.

I tested this synchronously and it worked.

What am I missing here?

2条回答
Summer. ? 凉城
2楼-- · 2019-08-16 13:09

Since you're working with background threads, you will need to marshal any code that plays with the UI to the UI thread.

task.ContinueWith(x => {
    Dispatcher.Invoke(() =>
        {
        label1.Content = task.Result; 
        },
        null);
});
查看更多
够拽才男人
3楼-- · 2019-08-16 13:30

You don't explain what "it doesn't do that" means. I assume you're getting an exception because you're trying to manipulate a UI element from the wrong thread?

The problem is this code:

task.ContinueWith(x => {
    label1.Content = task.Result; 
});

You're not specifying which thread you want your continuation to run on, so it could be running on any thread. It's probably going to run on the same thread as your first task, i.e., a thread pool thread. Since you're not allowed to access UI from a thread other than the thread it was created on, that means your label1.Content assignment will fail with an exception.

The fix is simple: run your continuation on the UI thread. Change the above code to this:

task.ContinueWith(x => {
    label1.Content = task.Result; 
}, TaskScheduler.FromCurrentSynchronizationContext());
查看更多
登录 后发表回答