0

我需要编写扩展方法,它可以像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;
    }
}
4

1 回答 1

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不会总是在主线程上运行延续。它将从添加延续时处于活动状态的上下文中运行延续。如果您从主线程添加延续(即使它正在运行的任务不在主线程中),那么您很好,但是如果您实际上从后台线程/上下文附加延续,那么它将运行在那种背景下。

于 2013-04-30T14:03:50.333 回答