我正在编写一个包含几个线程的程序,每个程序都有一个while循环,直到用户指定它应该停止.我想到了退出循环的几种方法,以及随后的线程,并在下面概述了这些方法.
问题
以下是方法.
该bool方法
最初,我已经声明了一个bool并且刚刚声明循环运行直到用户将bool设置为false : while(running) { Thread.Sleep(10); /*do work*/ }. 然后我思索是否完全是线程安全的.如果编译器进行了一些优化并将bool移动到寄存器,该怎么办?在这种情况下,线程会看到bool的不同值.因此,我使用volatile关键字标记bool 以避免编译器优化.
该ManualResetEvent方法
我的下一个方法是创建一个ManualResetEvent,并且只是说,当WaitOne()为false时bool运行:while(!mre.WaitOne(10)) {/*do work*/}.这将阻塞10ms,然后一遍又一遍地运行循环,直到我们这样做mre.Set()并且循环退出.
该CancellationToken方法
我还没有尝试过这种方法,但是我读了几个人们喜欢用这种方式取消线程的地方.它显然是线程安全的.可以定义一个CancellationTokenSource,调用它cts,然后传递cts.Token给新线程运行的方法,并使用if语句检查是否已请求取消:while(!token.IsCancellationRequested) { Thread.Sleep(10); /*do work*/ }
更新1:
我发现了一篇类似的帖子,得出的结论是该MRE方法明显慢于该CancellationToken方法.有关完整信息,请参阅此处:停止线程,ManualResetEvent,volatile boolean或cancellationToken
更新2:
当谈到将这种bool方法与其他两种方法进行比较时,Eric Lippert在这里有一个很好的答案:AutoResetEvent vs. boolean来阻止一个线程
更新3:
我找到了另一条相关的信息.取消取消后,取消权限无法重置.因此,当您只想暂时取消循环,以后再次启动它时,它并不理想.为此,MRE可能会更好(因为您可以根据自己的内容设置和重置).
c# multithreading manualresetevent cancellation cancellation-token
我像这样对字典进行排序:
var sortedListOfNodes = _nodeDictionary.Values.OrderBy((n) => n.Time);
Run Code Online (Sandbox Code Playgroud)
然后我选择了一个元素:
var selectedNode = sortedListOfNodes.First(n => n.Time - CurrentTime > new TimeSpan(1,0,0));
Run Code Online (Sandbox Code Playgroud)
然后我对该节点进行了一些处理,最后想从列表中删除该节点,而不破坏排序顺序。
下面会维持秩序吗?
sortedListOfNodes = (IOrderedEnumerable<Node>)sortedListOfNodes.Where(node => node != selectedNode);
Run Code Online (Sandbox Code Playgroud) 我想弄清楚为什么"第一项"在下面没有显示为橙色.根据特异性规则,选择器.one.two应具有20的特异性分数(两个类)..one li应该有11个(一个类,一个元素).所以它感觉它应该显示为橙色,而不是蓝色.
知道为什么不呢?
此外,作为一个侧面的问题,我为什么不能有之间的空间.one和.two在.one.two选择?这似乎适用于Chrome,但不是这里.
<!DOCTYPE html>
<html>
<head>
<style>
.one {
color: red;
}
.two {
color: green;
}
.one li {
color: blue;
}
.one.two {
color: orange;
}
</style>
</head>
<body>
<div>
<ul class="one two">
<li>Item One</li>
</ul>
</div>
</body>
</html>Run Code Online (Sandbox Code Playgroud)