任务结果上的事件已完成

时间:2012-10-29 15:09:22

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

  

可能重复:
  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.

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

3 个答案:

答案 0 :(得分:14)

任务的想法是你可以链接它们:

  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
    }

答案 1 :(得分:1)

您需要将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);

答案 2 :(得分:1)

看起来你正在开始一个后台任务来开始阅读推文,然后开始另一个任务来阅读结果而两者之间没有任何协调。

我希望您的任务能够继续执行另一项任务(请参阅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));