Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为并发C#代码编写单元测试?_C#_Multithreading_Unit Testing_Thread Safety - Fatal编程技术网

为并发C#代码编写单元测试?

为并发C#代码编写单元测试?,c#,multithreading,unit-testing,thread-safety,C#,Multithreading,Unit Testing,Thread Safety,我已经尝试解决这个问题很长时间了。我已经编写了一些示例代码,展示了C#中lock的用法。手动运行我的代码,我可以看到它的工作方式应该是这样的,但我当然希望编写一个单元测试来确认我的代码 我有以下ObjectStack.cs类: enum ExitCode { 成功=0, 错误=1 } 公共类对象堆栈 { 私有只读堆栈_objects=新堆栈(); 私有只读对象_lockObject=新对象(); 私有常量int numopopiterations=1000; 公共对象堆栈(IEnumerable

我已经尝试解决这个问题很长时间了。我已经编写了一些示例代码,展示了C#中
lock
的用法。手动运行我的代码,我可以看到它的工作方式应该是这样的,但我当然希望编写一个单元测试来确认我的代码

我有以下
ObjectStack.cs
类:

enum ExitCode
{
成功=0,
错误=1
}
公共类对象堆栈
{
私有只读堆栈_objects=新堆栈();
私有只读对象_lockObject=新对象();
私有常量int numopopiterations=1000;
公共对象堆栈(IEnumerable对象)
{
foreach(对象中的变量anObject){
推(一个物体);
}
}
公共无效推送(对象anObject)
{
_对象。推送(一个对象);
}
公共空间
{
_objects.Pop();
}
public void ThreadSafeMultiPop()
{
对于(VarI=0;i
Program.cs

公共类程序
{
私有常量int NumOfObjects=100;
私有常量int NumOfThreads=10000;
公共静态void Main(字符串[]args)
{
var objects=新列表();
对于(var i=0;iobjectStack.ThreadUnsafeMultiPop());
}
}
我试图编写一个单元,通过检查可执行文件的退出代码值(0=成功,1=错误),来测试线程不安全方法

在我的测试中,我尝试启动并运行应用程序可执行文件作为一个进程,有100次,每次都在测试中检查退出代码值。不幸的是,每次都是0


任何想法都非常感谢

从逻辑上讲,有一段非常小的代码可能会出现此问题。一旦其中一个线程进入弹出单个元素的代码块,则pop将工作,在这种情况下,该线程中的下一行代码将成功退出,或者pop将失败,在这种情况下,下一行代码将捕获异常并退出

这意味着,无论您在程序中投入了多少并行化,在整个程序执行堆栈中仍然只有一个点可以发生问题,即程序退出之前

代码确实是不安全的,但是在代码的任何一次执行中发生问题的概率极低,因为它要求调度程序决定不执行将干净地退出环境的代码行,而是让其他线程之一引发异常并带错误退出

要“证明”并发bug的存在是极其困难的,除了非常明显的bug,因为您完全依赖于调度器决定做什么

在查找其他一些帖子时,我看到了这篇与Java相关的帖子,但引用了C#:

它包括一个链接,该链接可能对您有用:


希望这是有用的,如果不是,请道歉。测试并发性本质上是不可预测的,编写示例代码也是不可预测的。

感谢所有的输入!尽管我同意由于调度器执行等原因,这是一个很难检测到的并发问题,但我似乎已经找到了一个可以接受的解决方案

我编写了以下单元测试:

[TestMethod]
public void可执行文件\进程\线程\安全()
{
const string executablePath=“Thread.Locking.exe”;
对于(变量i=0;i<1000;i++){
var process=new process(){StartInfo={FileName=executablePath};
process.Start();
process.WaitForExit();
if(process.ExitCode==1){
Assert.Fail();
}
}
}
当我运行单元测试时,似乎
程序.cs中的
并行.For
执行有时会抛出奇怪的异常,因此我不得不将其更改为传统的For循环:

公共类程序
{
私有常量int NumOfObjects=100;
私有常量int NumOfThreads=10000;
公共静态void Main(字符串[]args)
{
var objects=新列表();
对于(var i=0;iobjectStack.Thr