【问题标题】:awaited task not running asynchronously等待的任务没有异步运行
【发布时间】:2012-11-15 20:55:43
【问题描述】:

我正在尝试异步下载一些推特信息,它阻塞了 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 是一种自定义类型。

【问题讨论】:

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


    【解决方案1】:

    asyncawait 不会神奇地使阻塞代码变为非阻塞。 Linq-to-twitter 不是异步 API,将其粘贴在 Task.FromResult 中将无济于事。

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

    【讨论】:

    • 谢谢,我会研究一下 Task.Run,​​也许还有其他 API
    【解决方案2】:

    以前的答案很好,我只想补充已经说过的内容。 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> 类型的参数,resp,其中 T 是实体类型。在此示例中,T 是搜索。 resp.Status 让您知道在调用期间是否引发了异常,并允许您通过 resp.Error 属性进行访问。 resp.State 让您可以访问 IEnumerable,它是一个包含元数据和状态实体列表(推文)的单个搜索实体。

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

    @JoeMayo

    【讨论】:

    • 非常感谢乔!到目前为止,我很喜欢 linqtotwitter,我期待异步支持,继续努力
    【解决方案3】:

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

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

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

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

    【讨论】:

    • await 被赋予一个尚未完成的操作时,它会暂停该方法的执行并且阻塞线程。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-24
    • 2019-05-07
    • 1970-01-01
    • 2014-03-18
    • 1970-01-01
    • 2014-09-06
    • 1970-01-01
    相关资源
    最近更新 更多