【发布时间】:2013-10-11 10:41:55
【问题描述】:
我有一个遗留的(几年前的)WinForms 项目,目前在 .NET 4.0 中。当前的大多数数据检索使用BackgroundWorker 类/模式进行异步检索,但我正在添加一些新功能并希望使用async 模式(通过Async Targeting Pack)。该方法在开发和测试环境中运行良好,但我们的一些(非平凡数字)用户在程序中遇到了似乎与线程相关的错误;具体来说,如果您有除 UI 线程修改 UI 绑定数据之外的其他内容,您可能会看到什么。
其中一个旧控件的示例是:
public class LegacyControl
{
public void LoadData(int id)
{
while(isLoading)
{
Application.DoEvents();
Thread.Sleep(50);
}
isLoading = true;
currentId = id;
worker.RunWorkerAsync(id);
}
private bool isLoading;
private int currentId;
private object myData;
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
myData = RetrieveData(currentId);
}
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
bindingSource.DataSource = myData;
}
}
其中一个新控件的示例如下:
public class NewControl
{
public void LoadData(int id)
{
LoadDataAsync(id).ContinueWithErrorHandling(); // custom extension method to generically handle unhandled task exceptions.
}
private async Task LoadDataAsync(int id)
{
var data = await RetrieveSomeOtherDataAsync(id);
bindingSource.DataSource = data;
}
}
虽然我对这种可能性持怀疑态度,但我正在努力弄清楚这里发生了什么。是否有可能使用async/await 会以某种方式弄乱BackgroundWorker 并导致其RunWorkerCompleted 事件在后台线程而不是UI 线程上运行?
我可以尝试删除 TPL 代码,但由于我无法在我的环境中重现错误行为,我真的没有任何测试方法。
【问题讨论】:
标签: multithreading winforms task-parallel-library backgroundworker async-await