won*_*dra 0 c# deadlock async-await
首先,对于另一个“为什么我的异步操作挂起”问题感到抱歉,但我相信这个问题已经足够不同了。
调查了几十个类似的问题,异步操作死锁的问题要么是把自己锁在外面(.Result),使用有限的资源,要么错误地使用库组件(网络请求似乎很流行)。在以下示例中,我找不到上面的任何内容:
private async Task ExecuteAsync(Task<int> task)
{
// entering on current thread, that is the main UI thread
await task // execute "task" asynchronnously (on a different thread)
.ConfigureAwait(false); // when done, no need to return to main thread
MessageBox.Show("success"); // succes indicator
}
public MainWindow() //wpf window ctor
{
InitializeComponent();
this.Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
var task = new Task<int>(() => 42); // make an Action wrapping sychronnous method
// fire and forget, never caring for .Result, disard even the task
var _ = ExecuteAsync(task).ConfigureAwait(false);
}
Run Code Online (Sandbox Code Playgroud)
我已经尽我最大的努力对样本进行了评论,以解释事情(应该)如何运作,但我的解释中的某些内容肯定是错误的。即使MainWindowctor 没有死锁,() => 42也不会执行Action并且不会显示“成功”消息。经过一些调试后,我设法修复了示例(使用Task.FromResult),但我仍然不确定它现在有什么问题,更重要的是为什么。
我的推理中有什么错误,为什么该操作从未执行/完成?
你没有开始任务!你只是声明了它。简单地awaiting 它不会“触发”它。
private async Task ExecuteAsync(Task<int> task)
{
// at first do start the task
task.Start();
await task.ConfigureAwait(false);
MessageBox.Show("success");
}
Run Code Online (Sandbox Code Playgroud)
请注意,ConfigureAwait(false)这不保证会在不同的线程上继续执行。它只是说,你不要需要它被原来的线程上恢复。并且MessageBox.Show()不建议在非 UI 线程上恢复 UI 工作(如)。
正如NineBerry 所指出的,如果你想包装一个同步方法并让它在不同的线程上运行,你应该使用Task.Run():
var task = Task.Run(() => YourSynchronousCall());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
71 次 |
| 最近记录: |