3

我正在尝试异步下载一些 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 是一种自定义类型。

4

3 回答 3

5

async并且await不要神奇地使阻塞代码变为非阻塞。Linq-to-twitter 不是一个异步 API,将它放在 aTask.FromResult中将无济于事。

如果您想将查询推送到后台线程,您可以使用Task.Run而不是Task.FromResult. 更有效(但更复杂)的解决方案是使用异步 twitter API。

于 2012-11-28T05:11:35.953 回答
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<IEnumerable<T>> 类型的参数,resp,其中 T 是实体类型。在此示例中,T 是搜索。resp.Status 让您知道在调用期间是否引发了异常,并允许您通过 resp.Error 属性进行访问。resp.State 使您可以访问 IEnumerable<T>,它是一个包含元数据和状态实体(推文)列表的单个搜索实体。

底层 HTTP 调用确实异步执行,尽管它们使用 APM,而不是 C# 5.0 异步。我计划在未来对查询和命令进行更深入的异步研究,但今天使用的 LINQ to Twitter 非常有效。

@乔梅奥

于 2012-11-30T02:33:51.357 回答
-1

它阻塞了 UI 线程,因为这await就是本意。:)

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

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

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

于 2012-11-28T04:39:30.743 回答