具有Continuation方案的简单异步操作在WPF应用程序上不起作用 [英] Simple Async operation with Continuation scenario doesn't work on a WPF app

查看:53
本文介绍了具有Continuation方案的简单异步操作在WPF应用程序上不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了尝试异步操作,我对WPF应用程序有一个非常简单的操作.这是我完整的代码:

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.

我在这里想念什么?

推荐答案

您不会解释它不这样做"的含义.我以为您因为要从错误的线程中操作UI元素而遇到异常?

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?

问题是此代码:

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

您没有指定要在其上继续执行的线程,因此该线程可以在任何线程上运行.它可能会与第一个任务在同一线程上运行,即线程池线程.由于不允许您从创建该线程的线程之外的其他线程访问UI,因此这意味着您的 label1.Content 分配将失败,并发生异常.

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.

修复很简单:在UI线程上运行您的延续.将上面的代码更改为此:

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());

这篇关于具有Continuation方案的简单异步操作在WPF应用程序上不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆