私は、これはあなたが探しているものであると信じています。私はそのコードにコメントしているので、ほとんどの推論はコードに埋め込まれています。
基本的に、あなたの継続機能を使って、準備されたタスクをスピンアップさせてください。
Task currentTask;
CancellationTokenSource cancelTokenSource;
CancellationToken cancelToken;
Task newTask;
CancellationTokenSource newCancelTokenSource;
CancellationToken newCancelToken;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if(currentTask != null && currentTask.Status == TaskStatus.Running)
{
//Cancel the running task
cancelTokenSource.Cancel();
//Prepare a new Task to be triggered when the other cancels
//You could store new tasks/tokens in a dictionary if you wanted,also
//A new cancel token is always needed since the old stays cancelled
newCancelTokenSource = new CancellationTokenSource();
newCancelToken = newCancelTokenSource.Token;
newTask = new Task(()=>LongRunningTask(), newCancelToken);
//Continue that deals with both cancel and completion
//There is a different way to deal with this below, also
newTask.ContinueWith((previousTask)=>
{
if(previousTask.Status == TaskStatus.Cancelled)
{
label1.Text = "New Task Cancelled, Another New Starting";
BeginNewTask();
}
else
label1.Text = "New Task Ran To Completion";
},
//If cancelled token is passed, it will autoskip the continue
new CancellationTokenSource().Token, TaskContinuationOptions.None,
//This is to auto invoke the UI thread
TaskScheduler.FromCurrentSynchronizationContext());
}
else
{
cancelTokenSource = new CancellationTokenSource();
cancelToken = cancelTokenSource.Token;
//Start a fresh task since none running
currentTask = Task.Factory.StartNew(()=>LongRunningTask(),
cancelToken);
//OnCancelContinue
currentTask.ContinueWith((previousTask)=>
{
label1.Text = "First Task Cancelled, New Starting";
BeginNewTask();
},
//If cancelled token is passed, it will autoskip the continue
new CancellationTokenSource().Token,
TaskContinuationOptions.OnlyOnCancelled,
//This is to auto invoke the UI thread
TaskScheduler.FromCurrentSynchronizationContext());
//OnCompleteContinue
currentTask.ContinueWith((previousTask)=>
{
label1.Text = "First Task Ran To Completion";
},
//If cancelled token is passed, it will autoskip the continue
new CancellationTokenSource().Token,
TaskContinuationOptions.OnlyOnRanToCompletion,
//This is to auto invoke the UI thread
TaskScheduler.FromCurrentSynchronizationContext());
}
}
private void LongRunningTask()
{
for(int i = 0; i < 60; i++)
{
if(cancelToken.IsCancellationRequested)
cancelToken.ThrowIfCancellationRequested();
Thread.Sleep(1000);
}
}
private void BeginNewTask()
{
//Since the old task is cancelled, reset it with the new one
//Probably should do some error checks
currentTask = newTask;
cancelTokenSource = newCancelTokenSource;
cancelToken = newCancelToken;
//This is to make sure this task does not run on the UI thread
currentTask.Start(TaskScheduler.Default);
}
感謝。だから、私は正しい方向に行きました。 :-) –
Yahは、この作品の鍵です。 –