c# - Task.StartNew() 在 STA 模式下的工作方式不同?

标签 c# wpf multithreading async-await task-parallel-library

我对整个线程的事情还很陌生,所以希望有人能启发我。

我有一个 WPF 用户界面,通过单击按钮可以从中启动一个 DLL。单击按钮时,它会异步运行 dll,以便用户在 dll 执行其工作时仍然可以“导航”UI:

await Task.Factory.StartNew(new Action(() => strTime = 
                                             StartSync.Start(strPathFile,
                                             licManager.idCmsMediator)));

在我不得不在 STA 模式下运行此任务以打开 dll 中的窗口之前,这一直运行良好。所以我使用 this post 中描述的方法更改了这一行:

var scheduler = TaskScheduler.FromCurrentSynchronizationContext();
await Task.Factory.StartNew(new Action(() => strTime = 
                                             StartSync.Start(strPathFile,
                                             licManager.idCmsMediator)),
                                             System.Threading.CancellationToken.None, 
                                             TaskCreationOptions.None, scheduler);

但是现在,当我通过单击按钮运行 dll 时,我无法再在 UI 中导航了!好像它不再异步运行了!?如何在 STA 模式下启动任务但仍然能够导航 UI?

提前致谢

最佳答案

but now when I run the dll by clicking the button, I cannot navigate the UI

任务 != 线程。任务可能会也可能不会使用线程来完成它的工作。 当您使用时:

var scheduler = TaskScheduler.FromCurrentSynchronizationContext();

您要告诉任务工厂在当前捕获的同步上下文(即您的 UI 同步上下文)上执行给定的委托(delegate)。当您这样做时,它将在 UI 消息循环中执行。

this worked very well until I had to run this Task on STA mode to open windows in the dll

打开一个窗口应该在 UI 线程上完成,这就是为什么它会提示。您可以做的是将 CPU 绑定(bind)工作的执行推迟到后台线程,一旦您需要操作 UI,就将工作编码回去:

// Start CPU bound work on a background thread
await Task.Run(() => strTime = StartSync.DoCpuWork(strPathFile, 
                                                   licManager.idCmsMediator)));

// We're done awaiting, back onto the UI thread, Update window.

关于c# - Task.StartNew() 在 STA 模式下的工作方式不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30367662/

相关文章:

c# - 垃圾回收失败回收BitmapImage?

c++ - Qthread : worker for I/O queue

java - 无法使用下一个代码重现死锁

c# - 文本框和标签之间的一致空间和对齐方式

c# - TypeConverter 可以用于构造函数参数吗

c# - Unity+Firebase-数据库[错误] WebSocket : ws_0 - could not connect

c# - 如何防止模块附加到我的应用程序进程? C#

java - 子线程名称未在run()中打印

c# - 如何在 c# 中使用 selenium2 webdriver 单击特定坐标?

c# - 创建嵌入式mysql数据库