[英]Async await - it is the right Idea to avoid a blocking UI?
I thaught that using await / async is the best Idea to ensure a responsive UI. 我想使用await / async是确保响应式UI的最佳方法。 But I seem to do something wrong, because my Application freezes anyway.
但是我似乎做错了,因为我的应用程序始终冻结。
Wht I Try to do: A Button is launched and should await a long lasting operation. 我尝试执行的操作:按钮已启动,应等待长时间的操作。
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 });
}
}
The launched Class: 推出的课程:
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
It simply halts at the sleep and I am unsure what I have done wrong. 它只是在睡眠时停止,我不确定自己做错了什么。
Marking methods with async and await doesn't really do anything by itself. 用async和await标记方法本身并不能真正做任何事情。 You need to await a task:
您需要等待任务:
This would help: 这将有助于:
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
Yor StartLoading
method appears to be lacking any await
statements. 您的
StartLoading
方法似乎缺少任何await
语句。 The async
keyword does not magically make a method able to run asyncronously. async
关键字不能神奇地使方法能够异步运行。 You can await
a Task.Delay
as an async-alterative to your Thread.Sleep
. 您可以
await
Task.Delay
作为Thread.Sleep
的异步替代品。 For your very long operation, you probably need to spawn a new thread if it is CPU bound. 对于长时间的操作,如果受CPU限制,则可能需要生成一个新线程。 If it is IO bound, then it is a matter of whether you have access to an Async API that you can use.
如果是IO绑定的,则取决于您是否有权使用可以使用的Async API。
See Three Essential Tips For Asysnc on MSDN Channel 9 for the start of a good introduction. 请参阅MSDN Channel 9上有关Asysnc的三个基本技巧,以获取一个好的介绍的开始。
The problem is that your StartLoading task itself isn't asynchronous. 问题在于您的StartLoading任务本身不是异步的。 You can fix this using the following code:
您可以使用以下代码解决此问题:
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
Then you can use the code as follows: 然后,您可以使用以下代码:
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 });
}
});
}
I suspect the issue might be that the line "await eloader.StartLoading(excelFiles);" 我怀疑问题可能在于“等待eloader.StartLoading(excelFiles);”行。 is actually running on the same (UI) thread.
实际上在同一(UI)线程上运行。 You need to execute it like below.
您需要像下面那样执行它。 This will cause the method to be run on a ThreadPool thread.
这将导致该方法在ThreadPool线程上运行。
await Task.Run(eloader.StartLoading(excelFiles));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.