apr*_*ate 6 .net c# multithreading caching asynchronous
我正在查看http://www.albahari.com/threading/part4.aspx中描述的有关内存屏障的部分, 并试图制作"我们真的需要锁定和"下提供的示例的异步/等待版本壁垒"?
public class Program
{
static void Main(string[] args)
{
TestAsync();
Console.ReadKey(true);
}
private static async void TestAsync()
{
bool complete = false;
Func<Task> testFunc = async () =>
{
await Task.Delay(1000);
bool toggle = false;
while (!complete) toggle = !toggle;
};
var task = testFunc();
Thread.Sleep(2000);
complete = true;
await task;
Console.WriteLine("Done");
}
}
Run Code Online (Sandbox Code Playgroud)
在没有调试的情况下在释放模式下运行时,程序将永远不会按照它所基于的原始线程示例完成.
但是,由于上下文保存的方式,我在async/await的印象下会阻止这些问题.或者在使用async/await时是否仍然适用所有线程安全规则?
这实际上是一个编译优化问题.当您在发布中编译时出于某种原因,它预测完成将永远不会是真的并无限运行您的应用程序.既然你是基于另一个例子,我猜你已经知道了.但就async/await而言,它不能归咎于它.
要完成这项工作,您仍然需要将complete设置为volatile变量,如下所示:
static volatile bool complete = false;
Run Code Online (Sandbox Code Playgroud)
这将告诉编译器每个周期检查它,无论它是否有效.
我不是说我同意它,但正在发生的事情是编译器看到完全没有变化直到while(!complete)部分,并且因为没有volatile关键字它决定它永远不会改变为优化性能.
另一种使这项工作的方法是删除编译器优化.您可以单击项目"属性",然后单击"构建"选项卡,并取消选中"优化代码".然后它将在发布中工作.
| 归档时间: |
|
| 查看次数: |
786 次 |
| 最近记录: |