【发布时间】:2013-03-15 20:22:21
【问题描述】:
我正在使用 async / await 模式对一个对象执行一些 CPU 繁重的操作(我的方法是可等待的),它按预期工作而不会阻塞 UI 线程。
但是,当我将对象作为参数传递给新窗口的 ctor 时(新窗口是需要访问已处理对象的日志记录窗口),我的 UI 线程会阻塞(我有点理解为什么)。
为了解决这个问题,我可以将计算的执行包装在一个
中Task.Run(async () => { await _myObject.PerformCalculations(); });
然后简单地调用
var logWindow = new LogWindow(_myObject);
logWindow.Show();
这可行(当然),但是当对象引发事件时我有很多调度程序调用,如果没有 Task.Run 调用,我就不必处理这些。
所以,我的问题是,我能否以某种方式在不调用 Task.Run 的情况下仍然将对象传递到日志记录窗口而不阻塞我的 UI 线程?
编辑
我很抱歉这个精简的例子,我实际上是想让这个问题尽可能简单易懂,结果惨遭失败。
以更一般的方式:我有一个在特定条件下引发事件的对象。引发事件时,我想在 UI 上执行更新。事件总是从使用 Task.Run(...) 创建的线程中触发。因此,调度程序调用 UI 线程。所以,我想使用 async / await 执行计算(已经有效)并将对象传递到我的日志记录窗口(块)。
当我使用 Task.Run 时,当然一切正常,但无论我从 UI 线程订阅对象的事件,我都必须使用调度程序调用 UI 线程,因为事件从 Task.Run 线程触发。运行创建。我想避免这些调度程序调用。 事实上,如果我不将对象传递给日志记录窗口并调用 Show() 方法,UI 线程就不会阻塞,一切都会按预期工作。事件处理程序中不需要调度程序调用。
【问题讨论】:
-
当您已经在调用
Task.Run时,无需使用异步委托。只需使用Task.Run(_myObject.PerformCalculations) -
哇。乔恩斯基特本人。 :) 谢谢!但是,它并不像我的示例所暗示的那么简单。我必须使用委托,因为我有多个命令,实际上我将命令包装在委托内的 try/catch 块中。
-
logWindow.Show();粘贴代码时不知何故丢失了。
-
但即便如此,您真的需要它作为异步委托吗?老实说,你的问题真的不清楚。
-
你的问题我不清楚。当对象引发事件时,您提到调度程序调用。能详细点吗?
标签: c# wpf multithreading asynchronous async-await