我有一个长时间运行的方法,我做了异步。我也使我的按钮单击处理程序异步,但是当我尝试在完成长方法后单击我的按钮时,它会告诉我它无法从另一个线程访问它。这是代码:
private void Migrate()
{
for (int i = 2; i <= excelData.GetUpperBound(0); i++)
{
var poco = new ExpandoObject() as IDictionary<string, object>;
foreach (var column in distributionColumnExcelHeaderMappings)
{
if (column.ColumnIndex > 0)
{
var value = excelData[i,column.ColumnIndex]?.ToString();
poco.Add(column.DistributionColumnName.Replace(" ", ""), value);
}
}
pocos.Add(poco);
}
migrationRepository.BulkInsert(insertToTable, "Id", pocos);
}
private async void btnMigrate_Click(object sender, EventArgs e)
{
Task task = new Task(()=> Migrate());
task.Start();
lblStatus.Text = "Migrating data....";
await task;
lblStatus.Text = "Migration Complete";
}
单击该按钮时,我会看到状态Migrating data....
。完成后,它会在lblStatus.Text = "Migration Complete"
上抛出错误。我想等待之后,它会回到UI线程吗?
我清除了大部分代码,它仍然会抛出相同的错误。这是一个VSTO excel插件。这可能是问题的一部分吗?
private void Migrate()
{
}
private async void btnMigrate(object sender, EventArgs e)
{
Task.Run(()=>Migrate());
lblStatus.Text = "Done"; //still get error here
}
答案 0 :(得分:0)
尝试将代码更新为以下内容:
不是创建任务然后手动启动它,而是将其更新为等待Task.Run:
private async void btnMigrate_Click(object sender, EventArgs e)
{
lblStatus.Text = "Migrating data....";
await Task.Run(()=> Migrate());
lblStatus.Text = "Migration Complete";
}
修改强>
您可以使用辅助方法来检查在更新之前是否需要调用标签。
private async void btnMigrate_Click(object sender, EventArgs e)
{
SetLabelText(lblStatus, "Migrating data....");
await Task.Run(()=> Migrate());
SetLabelText(lblStatus, "Migration complete.");
}
private void SetLabelText(Label label, string text)
{
if (label.InvokeRequired)
{
label.BeginInvoke((MethodInvoker) delegate() {label.Text = text;});
}
else
{
label.Text = text;
}
}