C#任务UI死锁

C#任务UI死锁,c#,asynchronous,task,deadlock,C#,Asynchronous,Task,Deadlock,我知道有很多关于任务死锁的帖子,但我就是找不到正确的解决方案 所以我基本上有这样的设置: public event EventHandler StateChangedEvent; public bool Busy { ... set { ... this.StateChangedEvent?.Invoke(this, EventArgs.Empty) } } public void Main() { ... this

我知道有很多关于任务死锁的帖子,但我就是找不到正确的解决方案

所以我基本上有这样的设置:

public event EventHandler StateChangedEvent;
public bool Busy
{
    ...
    set
    {
        ...
        this.StateChangedEvent?.Invoke(this, EventArgs.Empty)
    }
}
public void Main()
{
    ...
    this.StateChangedEvent += this.OnStateChangedEvent;
}
public void OnStateChangedEvent(object sender, EventArgs e)
{
    this.TextBox.Invoke(() => this.TextBox.Text = "Change");
    this.Invoke(() => this.Cursor = Cursors.WaitCursor);
}
public void ButtonAction_Click(object sender, EventArgs e) //actually part of an API with an virtal - override method on between. Can't change here to async
{
    ...
    Task.Run(async () => await this.AsyncDoStuff()).Wait();
    ... // Synchron stuff needs to be done afterwards
}
public async Task AsyncDoStuff()
{
    this.Busy = true; //Causes Deadlock
    await Stuff1();
    await Stuff2();
}
所以在现实中,这些调用在不同的类中被分割,但基本结构仍然存在。是的,我知道我应该一直采用异步方式,但假设第一个
按钮操作单击
是API/框架的一部分,不能更改为异步。
我知道原因是因为我阻塞了UI线程,然后再次访问它…那么什么是最好的解决方案呢


提前谢谢

因此,从您的其他评论来看,ButtonAction\u Click中的代码似乎超出了您的控制范围,您无法更改它。不幸的是,这就是问题所在-此事件处理程序在工作完成之前完全阻塞UI线程。没有办法解除线程阻塞

您唯一的办法是避免与UI线程的任何阻塞交互

示例中的以下代码肯定会导致死锁,因为Invoke()将一直阻塞,直到UI(已被阻塞)响应为止:

this.TextBox.Invoke(() => this.TextBox.Text = "Change");
this.Invoke(() => this.Cursor = Cursors.WaitCursor);

您可以尝试使用BeginInvoke()而不是Invoke(),但不幸的结果是,这些UI更改在UI线程被取消阻止之前不会实际执行,并且在此之前,您的后台工作已经完成。不过,它可能会修复死锁。

ButtonAction\u是否在UI线程上单击run?