简体   繁体   English

WPF中的异步任务

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM