Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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# 使用任务的经典永无止境线程循环?_C#_Multithreading_Asynchronous_Task Parallel Library - Fatal编程技术网

C# 使用任务的经典永无止境线程循环?

C# 使用任务的经典永无止境线程循环?,c#,multithreading,asynchronous,task-parallel-library,C#,Multithreading,Asynchronous,Task Parallel Library,给出了一个非常常见的线程场景: 声明 private Thread _thread; private bool _isRunning = false; 开始 方法 private void NeverEndingProc() { while(_isRunning) { do(); } } 可能在异步tcp侦听器中使用,该侦听器等待回调,直到通过让线程耗尽而停止(\u isRunning=false) 现在我想知道:有没有可能对任务做同样的事情?使用取消令牌?或

给出了一个非常常见的线程场景:

声明

private Thread _thread;
private bool _isRunning = false;
开始

方法

private void NeverEndingProc() {
    while(_isRunning) {
        do();
    }
}
可能在异步tcp侦听器中使用,该侦听器等待回调,直到通过让线程耗尽而停止(
\u isRunning=false

现在我想知道:有没有可能对
任务
做同样的事情?使用
取消令牌
?或者,
Task
s仅适用于预期结束并报告状态的过程?

您当然可以通过将
NeverEndingProc
传递给
Task.Run
来完成此操作

但是,在功能上有一个重要的区别:如果异常从裸
线程中的
NeverEndingProc
传播出去,它将使进程崩溃。如果它位于
任务中
,它将引发
任务调度程序。未观察到的异常
,然后被静默忽略(从.NET 4.5开始)


也就是说,你可以探索其他选择,例如,几乎不需要“无限线程循环”。

使用Task+CancellationToken的一个原因是使各个进程及其取消更加独立。在您的示例中,请注意
NeverEndingProc
如何需要直接引用同一类中的
\u isRunning
字段。相反,您可以接受外部令牌:

开始:

public void StartNeverEndingProc(CancellationToken token) {
    Task.Factory.StartNew(() => NeverEndingProc(token), token);
}
方法:

private void NeverEndingProc(CancellationToken token) {
    while (true) {
        token.ThrowIfCancellationRequested();
        do();
    }
}
现在,取消由调用者管理,可以应用于多个独立的任务:

var instance = new YourClass();

var cts = new CancellationTokenSource();

instance.StartNeverEndingProc(cts.Token);  // start your task
StartOtherProc(cts.Token);  // start another task

cts.Cancel();  // cancel both

您只想使用tasks创建一个带有取消选项的无限循环?@deffis基本上是的。我曾被告知是“公正”线程,但在更高的层次上,它们的行为略有不同,但用途相同。不过,我可能在这一点上错了。我认为
\u正在运行
应该是
易失的
。否则,编译器可能会意识到它不是从当前线程修改的,并在循环开始之前只检查一次。
TaskCreationOptions.longlunning
是必需的,不是吗?因此,使用
TaskCreationOptions
和“DefaultScheduler”启动工厂.StartNew
Task.Run
更可取。如果我错了,请纠正我。反应式扩展听起来很有希望,但目前我没有时间钻研另一个新工具。:)@SriramSakthivel:
longlunning
只是一个提示。除非您在启动“无限循环”任务时已经在进行非常密集的并行处理,否则这是不必要的。和
Task.Run
使用默认的计划程序。@stephenleary我不确定你所说的“它是不必要的”是什么意思。如果没有那个线程池,它将使用池的线程,对吗?启用这一功能将为任务创建专用线程,允许池中的线程处理其他cpu密集型的小操作?@ErwinMayer:我相信是这样,但我不能完全确定。
var instance = new YourClass();

var cts = new CancellationTokenSource();

instance.StartNeverEndingProc(cts.Token);  // start your task
StartOtherProc(cts.Token);  // start another task

cts.Cancel();  // cancel both