Реализация BackgroundWorker's RunWorkerCompleted с помощью задач - PullRequest
1 голос
/ 24 мая 2011

У меня есть приложение WPF MVVM.В одной из моделей представления у меня есть следующее:

this.GoCommand = new RelayCommand(() =>
{
    var scheduler = TaskScheduler.FromCurrentSynchronizationContext();

    Task.Factory.StartNew(() =>
        {
            for (int i = 0; i < 100; ++i)
            {
                this.Progress = i + 1;
                Thread.Sleep(30);
            }
        }).ContinueWith(task =>
            {
                // should act like RunWorkerCompleted
                this.DoSecondTask();
            },
            scheduler
        );
});

private void DoSecondTask()
{ 
    Task.Factory.StartNew(() =>
        {
            for (int i = 0; i < 100; ++i)
            {
                // repeated task for simplicity
                this.Progress = i + 1;
                Thread.Sleep(30);
            }
        }).ContinueWith(task =>
            {
                this.Status = "Done.";
            }
        );
}

Когда я нажимаю кнопку, привязанную к GoCommand, я вижу, как индикатор выполнения перемещается от 1-100.Когда ContinueWith выполняет DoSecondTask, эта задача выполняется в потоке пользовательского интерфейса.Как изменить функцию DoSecondTask для запуска второго цикла for в новом потоке (или вне потока пользовательского интерфейса)?

1 Ответ

2 голосов
/ 24 мая 2011

Я нашел решение в этом ответе.Интересно отметить, что это не работает:

private void DoSecondTask()
{ 
    Task.Factory.StartNew(_ =>
        {
            for (int i = 0; i < 100; ++i)
            {
                // repeated task for simplicity
                this.Progress = i + 1;
                Thread.Sleep(30);
            }
        }, TaskScheduler.Default).ContinueWith(task =>
            {
                this.Status = "Done.";
            }
        );
}

Но это делает :

private void DoSecondTask()
{ 
    Task.Factory.StartNew(() =>
        {
            for (int i = 0; i < 100; ++i)
            {
                // repeated task for simplicity
                this.Progress = i + 1;
                Thread.Sleep(30);
            }
        }, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).ContinueWith(task =>
            {
                this.Status = "Done.";
            }
        );
}
...