我正在研究有关竞争条件的并行编程示例
在示例中,他们演示了处理竞争条件的隔离模式
为什么在这个示例中,创建任务时没有发生竞争条件,并且 stateObject 作为任务创建的一部分传递
我知道我们使用isolatedBalance来进行更新...但是在我们分配isolatedbalance = (int)stateObject
时,其他任务完成的余额不能在那里,即不是0而是100 ???
因此,如果有足够的任务,并且任务计划程序启动了早期任务,并在创建后续任务并分配帐户时完成。当其中 1 个任务完成时,余额值为 100 等对于正在开始的任务
class BankAccount
{
public int Balance { get; set; }
}
class Program
{
static void Main(string[] args)
{
var account = new BankAccount();
var tasks = new Task<int>[1000];
for (int i = 0; i < 1000; i++)
{
tasks[i] = new Task<int>((stateObject)=>
{
int isobalance = (int) stateObject;
for (int j = 0; j < 1000; j++)
{
isobalance ++;
}
return isobalance;
}, account.Balance);
tasks[i].Start();
}
Task.WaitAll(tasks);
for (int i = 0; i < 1000; i++)
{
account.Balance += tasks[i].Result;
}
Console.WriteLine("Epectecd valeu {0}, Counter value {1}",1000000,account.Balance);
// wait for input before exiting
Console.WriteLine("Press enter to finish");
Console.ReadLine();
}
}
最佳答案
您传递给 Task
构造函数的方法不会更新 account.Balance
,它仅使用 account.Balance
的初始值。它不更新它。 int
是按值传递。来自 MSDN :
值类型变量直接包含其数据,而引用类型变量则包含对其数据的引用。因此,将值类型变量传递给方法意味着将变量的副本传递给方法。方法内部对参数进行的任何更改都不会影响变量中存储的原始数据。如果您希望被调用的方法更改参数的值,则必须使用 ref 或 out 关键字通过引用传递它。为简单起见,以下示例使用 ref。
因此,直到调用 Task.WaitAll(tasks);
后,account.Balance
才会更新。 Task.WaitAll()
使代码停止在那里,直到所有任务完成。只有在那之后,一旦所有的结果都被计算出来。 account.Balance
将使用从 tasks[i].Result
返回的值进行更新。
关于c# - 并行编程竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8382401/