我有一个MockHttpListener用于单元测试的回调.我添加了一个锁,如下所示:
public void HandleRequest(HttpListenerContext context)
{
try
{
lock (m_guard)
{
do something short;
}
do the actual handling (longer)
}
catch (HttpListenerException e)
{
...
}
catch (Exception e)
{
...
}
...
}
Run Code Online (Sandbox Code Playgroud)
我遇到了一个问题,即测试失败是由于我们有"太长时间"的标准(在添加锁之前我没有在测试中遇到这个问题.)
我尝试了许多方法来确定问题,解决问题的唯一方法就是在try块之外进行锁定:
public void HandleRequest(HttpListenerContext context)
{
lock (m_guard)
{
do something short;
}
try
{
do the actual handling (longer)
}
catch (HttpListenerException e)
{
...
}
catch (Exception e)
{
...
}
...
}
Run Code Online (Sandbox Code Playgroud)
在相对于try块的锁定位置影响测试完成所花费的持续时间方面,行为改变是一致的.
任何人都知道原因吗?
这听起来可能是一个死锁——“做一些简短的事情”代码是否会调用任何本身需要锁定的代码?
以下代码按预期工作 - 并不是说这是一个好主意,但它会毫无问题地终止。
class Program
{
static void Main(string[] args)
{
Locks.DoStuff(Enumerable.Range(0, 10000).Select(e => 9999 - e).ToList());
}
}
static class Locks
{
public static void DoStuff(List<int> blah)
{
try
{
lock (blah)
{
for (var i = 0; i < blah.Count; i++)
{
blah[i] = 1000 / blah[i];
}
}
}
catch (DivideByZeroException e)
{
Trace.WriteLine("Exception - divided by zero");
}
}
}
Run Code Online (Sandbox Code Playgroud)