[英]Async Task in WPF
I tried to run a task for a WPF UI Code Behind . 我试图为WPF UI Code Behind运行任务。 but it doesn't work and noting happend when I use
Task.Factory
but it works when I use the code without Task.Factory
但是当我使用
Task.Factory
,它不起作用并注意到它,但是当我使用没有Task.Factory
的代码时它可以正常工作
public MainWindow()
{
InitializeComponent();
GetNews();
}
private void GetNews()
{
Task.Factory.StartNew(() =>
{
FeedReader reader = new FeedReader();
var news = reader.RetrieveFeed("http://www.bbc.com/feed/");
foreach (var item in news)
{
textBlock.Text = item.Title;
}
});
}
How can I use async/await or anything that prevent block main thread? 我如何使用async / await或任何阻止阻塞主线程的东西?
Nothing happens because an exception is thrown as you are trying to modify UI element outside of UI thread. 没有任何事情发生,因为当您尝试修改UI线程之外的UI元素时会抛出异常。 You should either use
textBlock.Dispatcher.Invoke
method or make FeedReader
asynchronous and use async/await
in your method, which is preferable. 您应该使用
textBlock.Dispatcher.Invoke
方法或使FeedReader
异步并在您的方法中使用async/await
,这是更可取的。
So the prefered solution would be (provided RetrieveFeed
is async method): 所以首选的解决方案是(假设
RetrieveFeed
是异步方法):
private async void GetNews()
{
FeedReader reader = new FeedReader();
var news = await reader.RetrieveFeed("http://www.bbc.com/feed/");
foreach (var item in news)
{
textBlock.Text = item.Title;
}
}
Alternatively you could wrap feed retrieval in a task, which will work with your current implementation: 或者,您可以将Feed检索包装在任务中,该任务将与您当前的实现一起使用:
private async void GetNews()
{
FeedReader reader = new FeedReader();
var news = await Task.Run(() => reader.RetrieveFeed("http://www.bbc.com/feed/"));
foreach (var item in news)
{
textBlock.Text = item.Title;
}
}
This approach will work because await will capture SynchronizationContext
of UI thread and will set value to the textbox in UI thread. 此方法将起作用,因为await将捕获UI线程的
SynchronizationContext
,并将值设置为UI线程中的文本框。
And the caveat here is that exceptions thrown in async void
method are never observed and are lost. 这里需要注意的是,
async void
方法中抛出的异常从未被观察到并且丢失了。 So you should wrap the code inside GetNews
method in try/catch
block and at least log the exception so you are aware of it. 因此,您应该将代码包装在
try/catch
块中的GetNews
方法中,并至少记录异常,以便您了解它。
You can use the async version to retrieve the feed 您可以使用异步版本来检索Feed
SyndicationFeed feed = await client.RetrieveFeedAsync(uri).AsTask(ct);
DisplayResults(feed);
Check the example from msdn . 查看msdn中的示例 。
It calls the Windows Runtime method, RetrieveFeedAsync
, and applies a .NET Framework extension method, AsTask
, to the returned IAsyncOperation
instance. 它调用Windows运行时方法
RetrieveFeedAsync
,并将.NET Framework扩展方法AsTask
应用于返回的IAsyncOperation
实例。 AsTask
represents the instance as a Task, so that you can await it. AsTask
将实例表示为任务,以便您可以等待它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.