Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# CancellationTokenSource是否突然取消?_C#_.net_Multithreading_Asynchronous_Task Parallel Library - Fatal编程技术网

C# CancellationTokenSource是否突然取消?

C# CancellationTokenSource是否突然取消?,c#,.net,multithreading,asynchronous,task-parallel-library,C#,.net,Multithreading,Asynchronous,Task Parallel Library,假设我有这样的东西: private CancellationTokenSource myToken; public void MyMyMethod() { myToken = new CancellationTokenSource(); var task = Task.Factory.StartNew(() => DoIt(myToken.Token), myToken.Token); Thread.Sleep(100); myToken.Cancel(); } p

假设我有这样的东西:

private CancellationTokenSource myToken;

public void MyMyMethod()
{
  myToken = new CancellationTokenSource();
  var task = Task.Factory.StartNew(() => DoIt(myToken.Token), myToken.Token);

  Thread.Sleep(100);
  myToken.Cancel();
}

public void MyOtherMethod()
{
  myToken.Cancel();
}

private void DoIt(CancellationToken token)
{
    token.ThrowIfCancellationRequested();
    try
    {
       for (int i = 0; i < 1000000; i++)
       {
         Console.WriteLine(i);
        }
    }
    catch (Exception ex)
    {
       string s = "";
    }
}
private CancellationTokenSource myToken;
公共void mymethod()
{
myToken=新的CancellationTokenSource();
var task=task.Factory.StartNew(()=>DoIt(myToken.Token),myToken.Token);
睡眠(100);
myToken.Cancel();
}
公共空间MyOtherMethod()
{
myToken.Cancel();
}
私有void DoIt(取消令牌令牌)
{
token.ThrowIfCancellationRequested();
尝试
{
对于(int i=0;i<1000000;i++)
{
控制台写入线(i);
}
}
捕获(例外情况除外)
{
字符串s=“”;
}
}
如果我调用myToken.Cancel,它会突然停止DoIt方法中的任务吗?还是我必须将令牌传递给DoIt并调用
myToken.ThrowIfCancellationRequested()
,以便在调用Cancel时抛出异常并突然停止

如果不将令牌传递给任务方法,我是否可以执行此操作

或者我必须在DoIt方法中监视token.IsCancellationRequested吗?

从这里读取,似乎在任务“真正”启动之前,但在任务排队之后,该令牌用于取消任务

这更像是一种取消已计划发生但尚未启动的任务的方法。一旦任务正在运行,取消它的唯一方法就是通过您自己在方法中的检查进行合作。如果没有这一点,您必须始终启动任务,然后在内部检查它,这将增加许多额外的、不必要的开销

您甚至可以通过从此处读取来从

中读取该标记。该标记似乎用于在任务“真正”启动之前取消任务,但在任务排队之后取消任务

这更像是一种取消已计划发生但尚未启动的任务的方法。一旦任务正在运行,取消它的唯一方法就是通过您自己在方法中的检查进行合作。如果没有这一点,您必须始终启动任务,然后在内部检查它,这将增加许多额外的、不必要的开销

你甚至可以从报纸上读到它

我必须将令牌传递给DoIt并调用myToken.ThrowIfCancellationRequested()吗

是的,你知道。TPL取消是协作的,这意味着您的线程函数必须定期检查是否已请求取消,如果已请求,则自行终止

另一种方法是调用
Thread.Abort()
,这通常不是一个好主意

我必须将令牌传递给DoIt并调用myToken.ThrowIfCancellationRequested()吗

是的,你知道。TPL取消是协作的,这意味着您的线程函数必须定期检查是否已请求取消,如果已请求,则自行终止



另一种方法是调用
Thread.Abort()
,这通常不是一个好主意。

正如我当时猜测的那样,您必须监视方法中的IsCancellationRequested属性。如果方法中有各种循环等,那么这可能非常棘手。我希望有办法中止这项任务。为什么会很棘手呢
ThrowIfCancellationRequested
抛出
OperationCanceledException
,这在停止所有循环方面做得相当好:)@Anton他的意思是,如果任务被取消,他必须每隔几行检查一次。。。他希望在任务中神奇地注入一个异常来停止线程。。。不知道这正是
Thread.Abort
所做的,并且它是邪恶的:-)所以我需要在我的方法中添加检查,以返回是否已取消,但异常抛出在哪里?@Jon在这里阅读了名为
异常的部分,该部分表示合作取消
,正如我当时猜测的那样,您必须监视方法中的IsCancellationRequested属性。如果方法中有各种循环等,那么这可能非常棘手。我希望有办法中止这项任务。为什么会很棘手呢
ThrowIfCancellationRequested
抛出
OperationCanceledException
,这在停止所有循环方面做得相当好:)@Anton他的意思是,如果任务被取消,他必须每隔几行检查一次。。。他希望在任务中神奇地注入一个异常来停止线程。。。不知道这正是
Thread.Abort
所做的,它是邪恶的:-)所以我需要在我的方法中添加检查,以在取消时返回,但异常抛出在哪里?@Jon在这里阅读了名为
异常的部分,它表示合作取消
,因此,例如,我将调用throwifcancellationrequest,我假设它只设置了一个内部属性。然后我很好地结束了我的任务。然后我在某个地方抛出了一个异常?
ThrowIfCancellationRequested()
抛出一个将终止线程函数的异常。TPL识别出这一点,并将
任务标记为
已取消
。这可能是我测试的方式,但线程仍在向控制台写入。查看我的更新问题和添加的代码。您需要在循环中调用
ThrowIfCancellationRequested()
。您还需要在
catch
块中重新抛出
operationCanceledException
。或者您可以从循环中的特定位置使用if stmt-“if(myToken.IsCancellationRequested)”,以更优雅的方式明确地退出流程,并可能完成或清理您正在做的事情。当然,这需要以合理的时间间隔返回到循环中的那个位置,例如,我将调用throwifcancellationrequest,我假设它只设置了一个内部属性。然后我很好地结束了我的任务。然后我在某个地方抛出了一个异常?
ThrowIfCancellationRequested()
抛出一个将终止线程函数的异常。TPL识别出这一点,并将
任务标记为
已取消
。这可能是我测试的方式,但线程仍在向控制台写入。查看我的更新问题和添加的代码。您需要