Я бы не советовал развертывать свой собственный класс Task, учитывая, что .NET 4 полностью поддерживает асинхронный запуск задач в фоновом режиме с использованием библиотеки параллельных задач
Тем не менее, вы можете делать то, что предлагает Рид, и использовать BackgroundWorker, который идеально подходит, или, если вы предпочитаете больше контролировать характер выполнения задачи, вы можете использовать класс Task из System.Threading.Tasks и реализовать что-то вроде этого:
public partial class MainWindow : Window
{
CancellationTokenSource source = new CancellationTokenSource();
SynchronizationContext context = SynchronizationContext.Current;
Task task;
public MainWindow()
{
InitializeComponent();
}
private void DoWork()
{
for (int i = 0; i <= 100; i++)
{
Thread.Sleep(500); //simulate long running task
if (source.IsCancellationRequested)
{
context.Send((_) => labelPrg.Content = "Cancelled!!!", null);
break;
}
context.Send((_) => labelPrg.Content = prg.Value = prg.Value + 1, null);
}
}
private void Start_Click(object sender, RoutedEventArgs e)
{
task = Task.Factory.StartNew(DoWork, source.Token);
}
private void Cancel_Click(object sender, RoutedEventArgs e)
{
source.Cancel();
}
}
В DoWork()
вы используете WPF SynchronizationContext и публикуете сообщения для обновления необходимого вам интерфейса пользователя.
В примере есть индикатор выполнения и элемент управления меткой, который обновляется на каждой итерации цикла for. Отмена поддерживается с помощью CancellationTokenSource
, который проверяется на каждой итерации.
Надеюсь, это поможет.