簡體   English   中英

同步等待異步方法在同一線程上完成

[英]Wait synchronously for an async method to finish on the same thread

有沒有一種方法可以同步等待在同一線程上運行的異步方法?

理想的效果是

  • 使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");
    }
}

有沒有一種方法可以同步等待在同一線程上運行的異步方法?

您無需同步等待。 通過使Worker async Task而不是async void您可以獲得所需的行為並刪除無用的TaskCompletionSource

private Task workerTask;
public Form()
{
     workerTask = Worker(cts.Token);
}

private async Task Worker(CancellationToken ct)
{
    while (!ct.IsCancellationRequested)
        await TaskEx.Delay(1000);
}

private async void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    cts.Cancel(); // request cancel
    await workerTask; // Wait for worker to finish before closing
}

我缺少Close()的實現,但是我懷疑您可以不用它,而是通過Close()表單事件來取消工作程序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM