gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 20:23:49 25 4
gpt4 key购买 nike

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

我有以下 ObjectStack.cs 类:

enum ExitCode
{
Success = 0,
Error = 1
}

public class ObjectStack
{
private readonly Stack<Object> _objects = new Stack<object>();
private readonly Object _lockObject = new Object();
private const int NumOfPopIterations = 1000;

public ObjectStack(IEnumerable<object> objects)
{
foreach (var anObject in objects) {
Push(anObject);
}
}

public void Push(object anObject)
{
_objects.Push(anObject);
}

public void Pop()
{
_objects.Pop();
}

public void ThreadSafeMultiPop()
{
for (var i = 0; i < NumOfPopIterations; i++) {
lock (_lockObject) {
try {
Pop();
}
//Because of lock, the stack will be emptied safely and no exception is ever caught
catch (InvalidOperationException) {
Environment.Exit((int)ExitCode.Error);
}
if (_objects.Count == 0) {
Environment.Exit((int)ExitCode.Success);
}
}
}
}

public void ThreadUnsafeMultiPop()
{
for (var i = 0; i < NumOfPopIterations; i++) {
try {
Pop();
}
//Because there is no lock, an exception is caught when popping an already empty stack
catch (InvalidOperationException) {
Environment.Exit((int)ExitCode.Error);
}
if (_objects.Count == 0) {
Environment.Exit((int)ExitCode.Success);
}
}
}
}

Program.cs:

public class Program
{
private const int NumOfObjects = 100;
private const int NumOfThreads = 10000;

public static void Main(string[] args)
{
var objects = new List<Object>();
for (var i = 0; i < NumOfObjects; i++) {
objects.Add(new object());
}
var objectStack = new ObjectStack(objects);
Parallel.For(0, NumOfThreads, x => objectStack.ThreadUnsafeMultiPop());
}
}

我正在尝试编写一个单元来测试线程不安全方法,方法是检查可执行文件的退出代码值(0 = 成功,1 = 错误)。

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

非常感谢任何想法!

最佳答案

从逻辑上讲,只有一小段代码会发生此问题。一旦其中一个线程进入弹出单个元素的代码块,那么弹出将起作用,在这种情况下,该线程中的下一行代码将成功退出,或者弹出将失败,在这种情况下,下一行代码将捕获异常并退出。

这意味着无论您在程序中进行了多少并行处理,在整个程序执行堆栈中仍然只有一个点可能会发生问题,那就是在程序退出之前。

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

要“证明”并发错误的存在是极其困难的,除了非常明显的错误,因为你完全依赖于调度程序决定做什么。

查找其他一些帖子,我看到这篇与 Java 相关但引用 C# 的帖子:How should I unit test threaded code?

它包含一个可能对您有用的链接:http://research.microsoft.com/en-us/projects/chess/

希望这是有用的,如果没有用,我们深表歉意。测试并发性本质上是不可预测的,编写示例代码也是如此。

关于c# - 为并发 C# 代码编写单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27998556/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com