我正在实现一个下载程序类,我正在使用任务,首先我创建了一个任务并用它传递了CancellationToken,当我取消任务时,任务被取消但任务的状态仍在运行,即使在我之后调用ThrowIfCancellationRequested()staus仍然是相同的。如果我抛出ThrowIfCancellationRequested(),请问状态是否为Canceled或Faulted。
这是我的代码:
public void Start()
{
//Start download
Status = DownloadStatus.Running;
CancellTS = new CancellationTokenSource();
CancelT = CancellTS.Token;
TaskStartDownload = Task.Run(() => { StartDownload(); }, CancelT);
}
private void StartDownload()
{
//Raise event download start
if (OnDownloadStart != null)
OnDownloadStart(this, new DownloadEventArgs(Id, 0, 0, 0, Controls, false));
byte[] buffer = new byte[4096];
long bytesToRead = Size;
Timer.Start();
while (!CancelT.IsCancellationRequested)
{
int currentBytesRead = Reader.Read(buffer, 0, buffer.Length);
Speed = currentBytesRead == 0 ? 0 : ((float)BytesRead / 1024) / Timer.Elapsed.TotalSeconds;
ProgressPercentage = ProgressPercentage + (currentBytesRead * 1.0 / Size) * 100;
TimeRemaining = (int)(((double)(Size - BytesRead) / 1024) / Speed);
if (currentBytesRead == 0)
{
Status = DownloadStatus.Completed;
//Raise event download start
if (OnDownloadComplete != null)
OnDownloadComplete(this, new DownloadEventArgs(Id, 100, 0, 0, Controls, false));
break;
}
Writer.Write(buffer, 0, currentBytesRead);
Writer.Flush();
//Raise progress event
this.OnDownloadProgress(this, new DownloadEventArgs(Id, Speed, ProgressPercentage, TimeRemaining, Controls, false));
BytesRead += currentBytesRead;
if (Status == DownloadStatus.Pause || Status == DownloadStatus.Cancel)
break;
}
Timer.Stop();
Reader.Close();
Reader = null;
Writer.Close();
if (CancelT.IsCancellationRequested)
{
try
{
CancelT.ThrowIfCancellationRequested();
}
catch (Exception ex)
{
Status = DownloadStatus.Cancel;
//Raise event download start
if (OnDownloadCancel != null)
this.OnDownloadCancel(this, new DownloadEventArgs(Id, 0, 0, 0, Controls, true));
File.Delete(FileNameWithPath);
}
}
TaskPrepareDownload.Dispose();
TaskStartDownload.Dispose();
}
public void Cancel()
{
if (TaskStartDownload == null)
{
return;
}
else
{
CancellTS.Cancel();
}
}
答案 0 :(得分:3)
调用ThrowIfCancellationRequested()后,不应该吞下异常,因此可以通知调用者(Start()方法)任务状态的变化。如果您吞下该异常,则认为该任务已成功完成(Status = RanToCompletion),或者如果您在触发取消后立即轮询该任务,则该任务仍在运行。
当您等待任务完成时,异常处理程序应放在调用者中。
请参阅MSDN Task Cancellation中的示例。