如何编写标准延续工作后执行的当前线程任务继续?

时间:2013-04-30 13:45:33

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

我需要编写扩展方法,它将像Task.ContinueWith()一样工作,但在主线程上和Task.ContinueWith()结束后。

public static Task ContinueWithOnMainThread(this Task task, Action action) {
    return task.ContinueWith(t => action(), TaskScheduler.FromCurrentSynchronizationContext());
}

此方法有效,但在Task.ContinueWith()

之前执行

这就是我测试它的方式:

public partial class MainWindow : Window {
    public MainWindow() {
        InitializeComponent();
        Loaded += delegate {
            LogThread("\nInMain ThredId: " + Thread.CurrentThread.ManagedThreadId);
            var task = new Task(InTask);
            task.ContinueWith(TaskContinue);
            task.ContinueWithOnMainThread(ReturnedToMainThread);
            task.Start();
        };
    }

    void InTask() {
        this.Dispatcher.Invoke(DispatcherPriority.DataBind, (Action<string>)LogThread, "\nInTask ThredId: " + Thread.CurrentThread.ManagedThreadId);
    }

    void TaskContinue(Task task) {
        this.Dispatcher.Invoke(DispatcherPriority.DataBind, (Action<string>)LogThread, "\nTaskContinue ThredId: " + Thread.CurrentThread.ManagedThreadId);
    }

    void ReturnedToMainThread() {
        LogThread("\nReturnedToMainThread ThredId: " + Thread.CurrentThread.ManagedThreadId);
    }

    void LogThread(string text) {
        TB.Text += text;
    }
}

1 个答案:

答案 0 :(得分:3)

所以问题就在这里:

var task = new Task(InTask);
task.ContinueWith(TaskContinue);
task.ContinueWithOnMainThread(ReturnedToMainThread);

您将两个续集添加到同一task。如果您希望在ReturnedToMainThread之后运行TaskContinue,那么您需要继续运行TaskContinue作为传递给ContinueWithOnMainThread的内容。你可以这样做:

var task = new Task(InTask);
task.ContinueWith(TaskContinue)
.ContinueWithOnMainThread(ReturnedToMainThread);

值得注意的是ContinueWithOnMainThread并不总是在主线程上运行延续。它将从添加延续时处于活动状态的上下文中继续运行。如果你从主线程添加延续(即使它之后运行的任务不在主线程中)那么你没问题,但如果你实际上从后台线程/上下文附加了延续,那么它将运行在那个背景环境中。