等待任务不是异步运行

时间:2012-11-28 04:17:36

标签: c# async-await linq-to-twitter

我正在尝试异步下载一些推文信息,它阻止了UI线程。我正在使用LinqToTwitter(http://linqtotwitter.codeplex.com/)下载信息。

这是对任务的调用

PublicTweetListBox.ItemsSource = await getTweets(twitterCtx);

这是任务本身

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;

}

我在等待下载列表的方式上做错了,如果有帮助,TweetViewModel是一种自定义类型。

3 个答案:

答案 0 :(得分:5)

asyncawait不会神奇地使阻止代码无阻塞。 Linq-to-twitter不是异步API,将其粘贴在Task.FromResult中将无效。

如果要将查询推送到后台线程,可以使用Task.Run代替Task.FromResult。更有效(但更具参与性)的解决方案是使用异步Twitter API。

答案 1 :(得分:1)

之前的答案很好,我只是想补充说的内容。 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));
        });
    }

MaterializedAsyncCallback采用类型为TwitterAsyncResult&lt; IEnumerable&lt; T&gt;&gt;,resp的参数,其中T是实体类型。在这个例子中,T是搜索。 resp.Status让您知道在调用期间是否引发了异常,并允许您通过resp.Error属性进行访问。 resp.State允许您访问IEnumerable&lt; T&gt;,它是一个包含元数据和状态实体列表(推文)的搜索实体。

底层HTTP调用确实异步执行,尽管它们使用APM,而不是C#5.0异步。我计划将来查看查询和命令的异步更近,但是今天LINQ to Twitter使用的内容非常有效。

@JoeMayo

答案 2 :(得分:-1)

它阻止了UI线程,因为这是await的意图。 :)

  

await运算符应用于异步方法中的任务   暂停方法的执行,直到等待的任务完成。   该任务代表了正在进行的工作。

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

IMO这是异步编程以同步方式工作的“黑客”。要在后台加载项目并在完成时更新ItemSource,请使用工作线程并调用'Dispatcher.Invoke'来更新ItemSource的结果。