簡體   English   中英

WPF中的異步任務

[英]Async Task in WPF

我試圖為WPF UI Code Behind運行任務。 但是當我使用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;
        }
    });
}

我如何使用async / await或任何阻止阻塞主線程的東西?

沒有任何事情發生,因為當您嘗試修改UI線程之外的UI元素時會拋出異常。 您應該使用textBlock.Dispatcher.Invoke方法或使FeedReader異步並在您的方法中使用async/await ,這是更可取的。

所以首選的解決方案是(假設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;
    }
}

或者,您可以將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;
    }
}

此方法將起作用,因為await將捕獲UI線程的SynchronizationContext ,並將值設置為UI線程中的文本框。

這里需要注意的是, async void方法中拋出的異常從未被觀察到並且丟失了。 因此,您應該將代碼包裝在try/catch塊中的GetNews方法中,並至少記錄異常,以便您了解它。

您可以使用異步版本來檢索Feed

SyndicationFeed feed = await client.RetrieveFeedAsync(uri).AsTask(ct);
DisplayResults(feed);

查看msdn中示例

它調用Windows運行時方法RetrieveFeedAsync ,並將.NET Framework擴展方法AsTask應用於返回的IAsyncOperation實例。 AsTask將實例表示為任務,以便您可以等待它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM