我正在一个新线程中运行一个Task,希望等待它完成。
var a = "logic before the task starts";
await Task.Factory.StartNew(() => MyHugeFunction(_token), _token);
var b = "logic after the task is finished";
它工作得很好,直到我开始用在线程内部调度
await Application.Current.Dispatcher.BeginInvoke(new Action(async () =>
{
SomeLogic();
}));
任务本身是有效的,但等待我运行的任务不再有效。一旦我在线程中进行调度,就会在主线程中分配var b。
我已经有了一些解决办法,但我只是想知道我是在做一些愚蠢的事情,还是这是由的其他情况引起的
我使用的是C#8.0和.Net Framework 4.7.2。
我正在一个新线程中运行一个Task,希望等待它完成。
您希望使用Task.Run
而不是StartNew
。StartNew
是一种危险的、低级的API,几乎不应该使用,在少数情况下,应该使用它,应该始终通过TaskScheduler
。
等待Application.Current.Dispatcher.BeginInvoke(new Action(async((=>
我马上就阻止你。首先,您使用async
显式地创建了一个Action
委托,这导致了一个应该避免的async void
方法。接下来,使用Dispatcher
来执行任何类型的Invoke
或BeginInvoke
实际上根本不应该执行。
相反,请使用Progress<T>
类型。这将您的逻辑保留在后台线程中,后台线程可以将对象作为更新传递给UI线程,UI线程决定如何在UI中显示这些进度更新。请注意,这里的关注点很好地分离了,每当人们开始使用Dispatcher
时,这种分离往往会消失。
StartNew
和Dispatcher
通常出现在SO答案和博客中,但无论如何,它们都是次优解决方案。