我认为使用await / async是确保响应式UI的最佳方法。但我似乎做错了什么,因为无论如何我的申请都冻结了。
我尝试做的事: 按钮已启动,应等待持续运行。
public async Task CmdLoadExcel()
{
// läd die excel datei
string[] excelFiles = this.GetExcelFiles();
ExcelLoader eloader = new ExcelLoader();
await eloader.StartLoading(excelFiles);
foreach (DataSet elem in eloader.Tables)
{
this.ActivateItem(new ExcelViewModel(elem) { DisplayName = elem.DataSetName });
}
}
推出的课程:
public async Task StartLoading(string[] files)
{
foreach (string file in files)
{
Stopwatch swatch = new Stopwatch();
swatch.Start();
System.Threading.Thread.Sleep(5000);
FileInfo finfo = new FileInfo(file);
using (ExcelPackage package = new ExcelPackage(finfo))
{
// very long operation
}
} // For Each
} // StartLoading
它只是在睡眠时停止,我不确定我做错了什么。
答案 0 :(得分:3)
使用async和await标记方法本身并没有真正做任何事情。您需要等待任务:
这会有所帮助:
public async Task StartLoading(string[] files)
{
return Task.Run(() =>
{
foreach (string file in files)
{
Stopwatch swatch = new Stopwatch();
swatch.Start();
System.Threading.Thread.Sleep(5000);
FileInfo finfo = new FileInfo(file);
using (ExcelPackage package = new ExcelPackage(finfo))
{
// very long operation
}
} // For Each
};
} // StartLoading
答案 1 :(得分:2)
Yor StartLoading
方法似乎缺少任何await
语句。 async
关键字不会神奇地使方法能够异步运行。您可以await
Task.Delay
作为Thread.Sleep
的异步替换。对于您的长时间操作,如果它受CPU限制,您可能需要生成一个新线程。如果它是IO绑定的,那么您是否可以访问可以使用的Async API是一个问题。
有关良好介绍的开始,请参阅MSDN第9频道上的Three Essential Tips For Asysnc。
答案 2 :(得分:1)
问题是您的StartLoading任务本身不是异步的。您可以使用以下代码解决此问题:
public Task StartLoading(string[] files)
{
return Task.Factory.StartNew(() =>
{
foreach (string file in files)
{
Stopwatch swatch = new Stopwatch();
swatch.Start();
System.Threading.Thread.Sleep(5000);
FileInfo finfo = new FileInfo(file);
using (ExcelPackage package = new ExcelPackage(finfo))
{
// very long operation
}
} // For Each
});
} // StartLoading
然后您可以按如下方式使用代码:
public Task CmdLoadExcel()
{
// läd die excel datei
string[] excelFiles = this.GetExcelFiles();
ExcelLoader eloader = new ExcelLoader();
var task = eloader.StartLoading(excelFiles);
return task.ContinueWith(t =>
{
foreach (DataSet elem in eloader.Tables)
{
this.ActivateItem(new ExcelViewModel(elem) { DisplayName = elem.DataSetName });
}
});
}
答案 3 :(得分:1)
我怀疑问题可能是“await eloader.StartLoading(excelFiles);”实际上是在同一个(UI)线程上运行。你需要像下面这样执行它。这将导致该方法在ThreadPool线程上运行。
await Task.Run(eloader.StartLoading(excelFiles));