简体   繁体   English

等待任务不是异步运行

[英]awaited task not running asynchronously

I'm trying to download some twitter info asynchronously and it's blocking the UI thread. 我试图异步下载一些推特信息,它阻止了UI线程。 I'm using LinqToTwitter (http://linqtotwitter.codeplex.com/) to download the info. 我正在使用LinqToTwitter(http://linqtotwitter.codeplex.com/)下载信息。

Here's the call to the task 这是对任务的调用

PublicTweetListBox.ItemsSource = await getTweets(twitterCtx);

And here's the task itself 这是任务本身

async Task<List<TweetViewModel>> getTweets(TwitterContext twitterCtx)
{       
    var tweetList = await Task.FromResult<List<TweetViewModel>>(
    (from tweet in twitterCtx.Status
    where tweet.Type == StatusType.User
    && tweet.ScreenName == UserName.Text
    select new TweetViewModel
    {
        Name = tweet.User.Name,
        Tweet = tweet.Text,
        ImageUrl = tweet.User.ProfileImageUrl
    })
    .ToList());

    return tweetList;

}

I'm doing something wrong in the way I await downloading the list, TweetViewModel is a custom type if that helps. 我在等待下载列表的方式做错了,TweetViewModel是自定义类型,如果有帮助的话。

async and await do not magically make blocking code non-blocking. asyncawait不会神奇地使阻塞代码无阻塞。 Linq-to-twitter is not an asynchronous API, and sticking it in a Task.FromResult will do nothing. Linq-to-twitter不是异步API,并且将其粘贴在Task.FromResult中将不会执行任何操作。

If you want to push the querying to a background thread, you could use Task.Run instead of Task.FromResult . 如果要将查询推送到后台线程,可以使用Task.Run而不是Task.FromResult A more efficient (but more involved) solution would be to use an asynchronous twitter API. 更有效(但更具参与性)的解决方案是使用异步Twitter API。

Previous answers were good and I just want to add to what has been said. 以前的答案很好,我只想补充说的内容。 LINQ doesn't support C# 5.0 async, so here's what I did with LINQ to Twitter to support it: LINQ不支持C#5.0异步,所以这就是我用LINQ to Twitter做的事情来支持它:

    static void AsyncSearchSample(TwitterContext twitterCtx)
    {
        (from search in twitterCtx.Search
         where search.Type == SearchType.Search &&
               search.Query == "LINQ To Twitter"
         select search)
        .MaterializedAsyncCallback(resp =>
        {
            if (resp.Status != TwitterErrorStatus.Success)
            {
                Exception ex = resp.Error;
                // handle error
                throw ex;
            }

            Search srch = resp.State.First();
            Console.WriteLine("\nQuery: {0}\n", srch.SearchMetaData.Query);

            srch.Statuses.ForEach(entry =>
                Console.WriteLine(
                    "ID: {0, -15}, Source: {1}\nContent: {2}\n",
                    entry.ID, entry.Source, entry.Text));
        });
    }

The MaterializedAsyncCallback takes a parameter of type TwitterAsyncResult<IEnumerable<T>>, resp, where T is the entity type. MaterializedAsyncCallback采用类型为TwitterAsyncResult <IEnumerable <T >>,resp的参数,其中T是实体类型。 In this example T is Search. 在这个例子中,T是搜索。 The resp.Status lets you know if an exception was raised during the call and gives you access through the resp.Error property. resp.Status让您知道在调用期间是否引发了异常,并允许您通过resp.Error属性进行访问。 The resp.State gives you access to the IEnumerable<T>, which is a single Search entity that contains metadata and a list of Status entities (tweets). resp.State允许您访问IEnumerable <T>,它是一个包含元数据和状态实体列表(推文)的搜索实体。

The underlying HTTP calls do execute asynchronously, though they use APM, rather than C# 5.0 async. 底层HTTP调用确实异步执行,尽管它们使用APM,而不是C#5.0异步。 I have plans to look at async closer for both queries and commands in the future, but what LINQ to Twitter uses today is quite effective. 我计划在将来查看查询和命令的异步更接近,但是今天LINQ to Twitter使用的是非常有效的。

@JoeMayo @JoeMayo

It's blocking the UI thread because that is what await is meant to do. 它阻止了UI线程,因为这就是await的意图。 :) :)

The await operator is applied to a task in an asynchronous method to suspend the execution of the method until the awaited task completes. await运算符应用于异步方法中的任务,以暂停方法的执行,直到等待的任务完成。 The task represents ongoing work. 该任务代表了正在进行的工

http://msdn.microsoft.com/en-us/library/hh156528.aspx http://msdn.microsoft.com/en-us/library/hh156528.aspx

IMO this is a "hack" to async programming to work in a synchronous way. IMO这是异步编程以同步方式工作的“黑客”。 To load items in the background and update the ItemSource when complete, use a worker thread and a call to 'Dispatcher.Invoke' to update the ItemSource with the results. 要在后台加载项目并在完成时更新ItemSource ,请使用工作线程并调用'Dispatcher.Invoke'以使用结果更新ItemSource

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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