c#-使用Parallel.Invoke和静态变量时的怪异行为
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c#-使用Parallel.Invoke和静态变量时的怪异行为,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2051字,纯文字阅读大概需要3分钟。
内容图文
![c#-使用Parallel.Invoke和静态变量时的怪异行为](/upload/InfoBanner/zyjiaocheng/658/40f258994a8b4a2eab0f826a14ac9a6d.jpg)
我正在尝试测试C#并行方法,这是我的测试程序:
class Program
{
static int counter;
static void Main(string[] args)
{
counter = 0;
Parallel.Invoke(
() => func(1),
() => func(2),
() => func(3)
);
Console.Read();
}
static void func(int num)
{
for (int i = 0; i < 5;i++ )
{
Console.WriteLine(string.Format("This is function #{0} loop. counter - {1}", num, counter));
counter++;
}
}
}
我试图做的是拥有1个静态共享变量,每个函数实例会将其增加1.
我希望计数器将按顺序打印(1,2,3,…)
但是输出令人惊讶:
This is function #1 loop. counter - 0
This is function #1 loop. counter - 1
This is function #1 loop. counter - 2
This is function #1 loop. counter - 3
This is function #1 loop. counter - 4
This is function #3 loop. counter - 5
This is function #2 loop. counter - 1
This is function #3 loop. counter - 6
This is function #3 loop. counter - 8
This is function #3 loop. counter - 9
This is function #3 loop. counter - 10
This is function #2 loop. counter - 7
This is function #2 loop. counter - 12
This is function #2 loop. counter - 13
This is function #2 loop. counter - 14
谁能向我解释为什么会这样?
解决方法:
问题是您的代码不是线程安全的.例如,可能发生的情况是:
>函数2获取计数器的值以在Console.WriteLine()中使用它
>函数1获取计数器的值,调用Console.WriteLine(),使计数器递增
>函数1获取计数器的值,调用Console.WriteLine(),使计数器递增
>函数#2最终使用旧值调用Console.WriteLine()
另外,它本身也不是线程安全的,因此最终值可能不是15.
要解决这两个问题,可以使用Interlocked.Increment():
for (int i = 0; i < 5; i++)
{
int incrementedCounter = Interlocked.Increment(ref counter);
Console.WriteLine("This is function #{0} loop. counter - {1}", num, incrementedCounter);
}
这样,您将获得增量后的数字,而不是原始代码中的数字.同样,此代码仍不会以正确的顺序打印数字,但是您可以确保每个数字将被打印一次.
如果确实要按正确的顺序排列数字,则需要使用锁:
private static readonly object lockObject = new object();
…
for (int i = 0; i < 5; i++)
{
lock (lockObject)
{
Console.WriteLine("This is function #{0} loop. counter - {1}", num, counter);
counter++;
}
}
当然,如果执行此操作,实际上不会获得任何并行性,但是我认为这不是您的真实代码.
内容总结
以上是互联网集市为您收集整理的c#-使用Parallel.Invoke和静态变量时的怪异行为全部内容,希望文章能够帮你解决c#-使用Parallel.Invoke和静态变量时的怪异行为所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。