任务结果事件已完成

8
我正在使用以下代码:

可能是重复问题:
如何创建运行STA线程的任务(TPL)?

我正在使用以下代码:

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线程。 - Servy
3个回答

16

任务的设计理念是可以将它们链接起来:

  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

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

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));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接