pus*_* 22 5 c# multithreading unit-testing
我有一些旧代码,我正在尝试为其编写测试。该代码解析日志文件(在后台线程上),完成后触发传入的委托。
IE
public delegate void finread(LogData l, LRParseState l, string e="");
void Thread_ParseLog(object info) {
var info = ti as ThreadInfo;
// some time later
info.fin(log, state, error);
}
public static void ParseErrorLog(string log, finread fin){
var pts = new ParameterizedThreadStart(Thread_ParseLog);
new Thread(pts).Start(new ThreadInfo(log, fin));
}
Run Code Online (Sandbox Code Playgroud)
该代码是生产代码,一切正常,并且已经完成很长时间了,但是当我尝试测试它时,我得到“线程正在中止”。Thread_ParseLog 方法中引发异常。
测试看起来像这样:
void llt(string name, Action<LogData, LRParseState> test) {
finread d = (LogData l, LRParseState s, string e) => {
test(l, s);
};
LogReader.ParseErrorLog(name, d);
}
[TestMethod]
public void Create_LogReader_Big_Log() {
llt(ERROR_LOG, (log, state) => {
Assert.IsTrue(log != null); // never get here!
});
}
Run Code Online (Sandbox Code Playgroud)
测试数据较大,约55mb,正常处理需要500ms左右。
我还在输出窗口中收到错误:
抛出异常:mscorlib.dll 中的“System.Threading.ThreadAbortException”System.AppDomainUnloadedException:尝试访问已卸载的 AppDomain。如果测试启动了一个线程但没有停止它,就会发生这种情况。确保测试启动的所有线程在完成之前都已停止。
这似乎指出了某种线程同步问题,但我对正在测试的代码无能为力。
显然,这就是我编写测试的方式,我可以通过更改测试来修复它,但我不确定为什么会发生这种情况。
TIA。
使用同步机制(例如,ManualResetEvent在离开测试方法之前等待测试的异步部分完成)。
[TestMethod]
public void Create_LogReader_Big_Log() {
// Use this event to wait until the asynchronous code has been executed
// before leaving the test method
ManualResetEvent resetEvent = new ManualResetEvent(false);
LogData logDataReceived = null;
llt(ERROR_LOG, (log, state) => {
logDataReceived = log;
// Signal that the test has reached the end
resetEvent.Set();
});
// Wait for the event to be set
resetEvent.WaitOne();
// Additionally wait for a grace period to allow the other thread to fully terminate
Thread.Sleep(500);
// Now perform the asserts on the received data
Assert.IsTrue(logDataReceived != null);
}
Run Code Online (Sandbox Code Playgroud)