[英]Why this lock statement does not work
所以我有这个相当简单的代码。 看一看。
var monitor = new object();
var result = 0;
Task.Factory.StartNew(() =>
{
var childTaskFactory = new TaskFactory(TaskCreationOptions.AttachedToParent, TaskContinuationOptions.ExecuteSynchronously);
for (int i = 0; i < 5; i++)
{
childTaskFactory
.StartNew<int>(() => CreateRequest()) // this methods just return the integer value 10
.ContinueWith(task => { lock (monitor) { result += task.Result; } });
}
}).Wait();
基本上,我实例化了一个用于获取锁的新对象。 然后我将创建一个设置为0的int
变量。之后,我将创建一个父Task
,其中将包含5个子Task
,所有这些子任务都调用一个名为CreateRequest
的方法,该方法只会返回数字10(不要介意方法的名称)。 每个子Task
都有一个延续,该延续获得了monitor
锁定,并且仅将CreateRequest
方法返回的数字10添加到result
变量中。 在程序结束时,我希望变量result
包含值50。但事实并非如此。 我的意思是有时这样做,但有时将其设置为20、30或40。显然我误解了如何使用lock
语句,或者实现存在问题。 我很可能在代码中有一些错误。 此代码在Program
类的static Main
方法内部。
因为当其他所有任务都开始时,您的主要任务已完成。 它不会等到他们全部完成 。 因此,有时您会在所有子任务运行之前捕获result
的价值。
作为测试,将Thread.Sleep(1000)
放在Wait()
,您将看到result
按预期更新。 但是不要将其用于生产代码。 而是编写等待所有子任务完成的代码。
您还可以通过将子任务添加到列表中,然后在末尾添加断点来检查正在发生的情况。 如果然后在“本地”窗口中检查对象,则会看到某些任务的状态仍为“正在运行”。
请注意,将任务添加到列表中可能会影响执行,并导致结果更频繁地等于50。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.