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?