簡體   English   中英

異步等待UI死鎖

[英]Async Await UI Deadlock

我有一個基本類,用於顯示通過異步延遲淡入和淡出的通知,以使UI保持響應。

 public partial class Notification : Form
{
    public Notification(string message)
    {
        InitializeComponent();
        txtNotification.Text = message;
    }

    async new public void Show()
    {
        FadeIn();
        await Task.Delay(7000);
        FadeOut();
    }

    async void FadeIn()
    {
        Opacity = 0;
        base.Show();
        while (Opacity < 1.0)
        {
            await Task.Delay(50);
            Opacity += 0.05;
        }
        Opacity = 1;
    }

    async void FadeOut()
    {
        while (Opacity > 0.0)
        {
            await Task.Delay(50);
            Opacity -= 0.05;
        }
        Opacity = 0;
        Hide();
    }
}

我也有一個UI事件處理程序,它想要執行一些繁重的工作,然后顯示一個通知。

async public void MyHandler(args)
{
    await Task.Run(() => 
    {
            System.Diagnostics.Debug.WriteLine("Do something!");
    });
    new Notification("Work completed!").Show();
}

並且在通知FadeIn'await Task.Delay(50)'時遇到死鎖。 我是異步await malarkey的新手,但據我了解,我不能簡單地進行ConfigureAwait,因為我需要在UI線程上淡入通知,而我正在使用async並一直“一直”等待。 如果我只是簡單地刪除執行該工作的事件處理程序中的行,那么就沒有死鎖,但是我正在等待它完成,因此無法理解為什么我最終陷入死鎖。 我肯定在這里誤解了嗎?

根據要求,我現在刪除了異步void並減少了代碼:

 public partial class Notification : Form
{
    public Notification()
    {
        InitializeComponent();
    }

    async Task FadeIn()
    {
        Opacity = 0;
        base.Show();
        while (Opacity < 1.0)
        {
            await Task.Delay(50);
            Opacity += 0.05;
        }
    }
}

並且我發現該問題不會在WinForm應用程序中重現,但確實會按照Outlook AddIn中的描述重現。 為了簡化起見,我現在使用AddIn StartUp事件,以下代碼顯示通知沒有問題

    async private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {            
        await new Notification().FadeIn();
    }

但是此代碼會導致掛起/死鎖,如我之前所述

    async private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        await Task.Run(() =>
       {
           System.Diagnostics.Debug.WriteLine("Do something!");
       });
        await new Notification().FadeIn();
    }

我創建了一個新的AddIn,沒有其他代碼,所以我認為問題一定是Outlook。(?)

@StephenCleary提供了解決方案。 在有問題的代碼之前添加以下行。

SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext());

暫無
暫無

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

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