我见过许多从事件处理程序异步执行长时间运行的代码的示例。例如,下面是WPF中按钮单击的事件处理程序:
public async void Button_Click(object sender, EventArgs e)
{
await Task.Run(() => DoWork());
}
private int DoWork()
{
for (int i = 0; i < 10000000; i++) { }
return 42;
}
如果DoWork
比较复杂,比如写入数据库,那么单击多个按钮可能会导致多个线程同时尝试写入数据库。
如果不是有许多这样的Task.Run
调用,而是为所有非UI工作创建一个新的Thread
,会怎么样呢?任务可以使用BlockingCollection
之类的命令在这个线程上排队。
因为这个线程与UI线程是分开的,所以UI仍然是响应性的,并且单击多个按钮会将任务(按顺序)调度到同一个线程,从而避免并发问题。
这是个好主意吗?
发布于 2018-08-23 03:53:52
你所说的是一个可以在并行扩展中找到的QueuedTaskScheduler
。
也就是说,我不会简单地对所有操作进行排队。虽然您现在有了一个响应式的UI,但它看起来好像什么都没有发生。
我不会坚持做一个Task.Factory.StartNew。不能保证任务会启动新线程。任务和线程是两个不同的东西。默认的任务调度程序足够智能,可以判断是否有可用的必要资源来启动任务的新线程。如果您请求一组任务一次启动,队列将自动发生。
发布于 2018-08-23 03:56:43
对于长时间运行的操作,在大多数情况下使用异步是有意义的:Keep the UI thread responsive。
https://stackoverflow.com/questions/51974059
复制相似问题