使用异步方法让我的UI工作时遇到麻烦。这是我的代码的一部分
private async void btnDoOutput_Click(object sender, RoutedEventArgs e)
{
/* Initiliaze */
groupBoxConfiguration.IsEnabled = false;
var progressIndicator = new Progress<int>();
progressIndicator.ProgressChanged += (s,value) =>
{
progressExport.Value = (double)value;
labelPercentage.Content = "Export in progress : " + value + " %";
};
/* do Work */
switch (something)
{
case 1:
await method(input, output, options, progressIndicator);
break;
default: break;
}
/* Finalization */
groupBoxConfiguration.IsEnabled = true;
}
方法是
public async static Task<string> method(string input, string output, string options, IProgress<int> progress)
{
while(something)
{
//operations on input and output
if (progress != null)
{
progress.Report(percentage);
}
}
}
当我点击我的按钮时,UI冻结,仍然启用了groupBox,直到结束才显示进度。
答案 0 :(得分:1)
我认为你完全误解async
/ await
实际上是如何运作的。您的所有代码仍然在UI线程上运行,因为您实际上并没有告诉它。这意味着await
上的method
毫无意义,因为无论如何它都会同步运行。
async
/ await
的目的是允许调用代码继续处理,直到它遇到需要等待任务结果的部分代码。因此,在您的示例中,您需要更改method
正文以实际返回等待Task
public Task method(string input, string output, string options, IProgress<int> progress)
{
return Task.Run(() => {
while(something)
{
//operations on input and output
if (progress != null)
{
progress.Report(percentage);
}
}
});
}
答案 1 :(得分:-2)
首先请不要使用静态方法,特别是静态工作者。
我相信问题是你仍然在你的UI线程上(我根据你给出的代码做了一些疯狂的假设)。尝试使用Task<string>.Factory.StartNew(...)
,它应该自动调用UI线程。
注意可能需要使用调度程序并调用回UI线程以使进度条工作。