【发布时间】:2015-06-09 19:00:27
【问题描述】:
有没有办法同步等待在同一线程上运行的异步方法?
想要的效果是
- 让 Worker() 在 UI 线程上异步运行
- 同时等待Close()方法返回前完成
下面的例子进入了死锁,如果我让 Form1_FormClosing() 异步我不满足第二个条件。
public partial class Form1 : Form
{
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
CancellationTokenSource cts = new CancellationTokenSource();
public Form1()
{
InitializeComponent();
Show();
Worker(cts.Token); // async worker started on UI thread
}
async void Worker(CancellationToken ct)
{
while (!ct.IsCancellationRequested)
await TaskEx.Delay(1000);
tcs.SetResult(true); // signal completition
}
private void button1_Click(object sender, EventArgs e)
{
Close();
MessageBox.Show("This is supposed to be second");
}
private async void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
cts.Cancel(); // request cancel
tcs.Task.Wait(); // deadlock
await tcs.Task; // button1_Click() gets control back instead of Worker()
MessageBox.Show("This is supposed to be first");
}
}
【问题讨论】:
-
使用
await Task.Delay(1000, ct).ConfigureAwait(false)。和tcs.TrySetResult(true);。确保在Worker中执行的任何长时间操作都可以通过令牌取消。还要在工作人员中捕获OperationCanceledException,在这种情况下捕获tcs.SetCanceled()。 -
您实际上想要做什么?您已经说过您的解决方案尝试有什么问题,但您还没有说明您要解决的问题是什么。
-
你想让任务继续运行,还是在它暂停的任何中断点取消它?
-
@BenVoigt 我想在暂停的任何时候取消它。
标签: c# asynchronous async-await task deadlock