【问题标题】:Event on Task Result is done [duplicate]任务结果事件已完成[重复]
【发布时间】:2012-10-29 15:09:22
【问题描述】:

可能重复:
How to create a task (TPL) running a STA thread?

我正在使用以下代码:

var task = Task.Factory.StartNew<List<NewTwitterStatus>>(
        () => GetTweets(securityKeys),  
        TaskCreationOptions.LongRunning);

Dispatcher.BeginInvoke(DispatcherPriority.Background,
    new Action(() =>
    {
        var result = task.Result; // ERROR!!! The calling thread cannot access this object because a different thread owns it.
        RecentTweetList.ItemsSource = result;
        Visibility = result.Any() ? Visibility.Visible : Visibility.Hidden;
    }));

我得到了错误:

var result = task.Result; // ERROR!!! The calling thread cannot access this object because a different thread owns it.

我需要做什么来解决这个问题?

【问题讨论】:

  • 请记住,Task.Result 将阻塞直到结果可用,因此如果此代码没有出错,那么您将在等待任务完成时阻塞 UI 线程;那会很糟糕。您需要等待调用 UI 线程,直到实际得到结果。

标签: c# .net wpf task-parallel-library


【解决方案1】:

Tasks 的想法是你可以将它们链接起来:

  var task = Task.Factory.StartNew<List<NewTwitterStatus>>(
                            () => GetTweets(securityKeys),  
                            TaskCreationOptions.LongRunning
                        )
        .ContinueWith(tsk => EndTweets(tsk) );


    void EndTweets(Task<List<string>> tsk)
    {
        var strings = tsk.Result;
        // now you have your result, Dispatchar Invoke it to the Main thread
    }

【讨论】:

    【解决方案2】:

    您需要将 Dispatcher 调用移动到任务延续中,如下所示:

    var task = Task.Factory
        .StartNew<List<NewTwitterStatus>>(() => GetTweets(securityKeys), TaskCreationOptions.LongRunning)
        .ContinueWith<List<NewTwitterStatus>>(t =>
        {
            Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
                new Action(() =>
                {
                    var result = t.Result;
                    RecentTweetList.ItemsSource = result;
                    Visibility = result.Any() ? Visibility.Visible : Visibility.Hidden;
                }));
        },
        CancellationToken.None,
        TaskContinuationOptions.None);
    

    【讨论】:

      【解决方案3】:

      看起来您正在启动一个后台任务来开始阅读推文,然后在两者之间没有任何协调的情况下启动另一个任务来阅读结果。

      我希望您的任务在延续中有另一个任务(请参阅http://msdn.microsoft.com/en-us/library/dd537609.aspx),并且在延续中您可能需要调用回 UI 线程......

      var getTask = Task.Factory.StartNew(...);
      var analyseTask = Task.Factory.StartNew<...>(
      ()=> 
      Dispatcher.Invoke(RecentTweetList.ItemsSource = getTask.Result));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-05-06
        • 1970-01-01
        • 2020-04-14
        • 1970-01-01
        • 1970-01-01
        • 2021-09-09
        • 1970-01-01
        相关资源
        最近更新 更多