为并发C#代码编写单元测试?
我已经尝试解决这个问题很长时间了。我已经编写了一些示例代码,展示了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
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