Bec*_*Lou 8 c# multithreading exception
我有一些代码启动了几个线程让它们执行,然后使用while循环检查当前时间是否超过设置的超时时间,或者是否已经处理了正确的结果数(通过检查class object)(用a Thread.Sleep()来循环之间等待)
一旦while循环设置为exit,它就会调用Abort()线程并将数据返回给调用该方法的函数.
在调试和单步执行代码时,我发现在单独的线程上运行的代码中可能存在异常,在某些情况下我会适当地处理这些异常,而在其他时候我不想做任何具体的事情.
我所看到的是我的代码进入while循环并且线程休眠,然后我的函数(数据或异常)都没有返回任何内容.代码执行完全停止.
有什么想法会发生什么?
代码示例:
System.Threading.Thread sendThread =
new System.Threading.Thread(new System.Threading.ThreadStart(Send));
sendThread.Start();
System.Threading.Thread receiveThread =
new System.Threading.Thread(new System.Threading.ThreadStart(Receive));
receiveThread.Start();
// timeout
Int32 maxSecondsToProcess = this.searchTotalCount * timeout;
DateTime timeoutTime = DateTime.Now.AddSeconds(maxSecondsToProcess);
Log("Submit() Timeout time: " + timeoutTime.ToString("yyyyMMdd HHmmss"));
// while we're still waiting to receive results & haven't hit the timeout,
// keep the threads going
while (resultInfos.Count < this.searchTotalCount && DateTime.Now < timeoutTime)
{
Log("Submit() Waiting...");
System.Threading.Thread.Sleep(10 * 1000); // 1 minute
}
Log("Submit() Aborting threads"); // <== this log doesn't show up
sendThread.Abort();
receiveThread.Abort();
return new List<ResultInfo>(this.resultInfos.Values);
Run Code Online (Sandbox Code Playgroud)
所以,你真的不应该在线程上使用Sleep方法进行同步.这就是ManualResetEvent等同步类的用途,以及异步编程模型(IAsyncResult实现).
这里更好的方法是创建一个委托,其中包含要异步运行的方法的签名.然后,将作为异步操作的入口点的方法组分配给该委托的实例,并在委托实例上调用BeginInvoke.
从那里,你将运行你的循环,期望你将在委托上调用BeginInvoke返回的IAsyncResult实现的AsyncWaitHandle属性返回的WaitHandle上调用WaitOne的重载.
这将减少对Sleep方法的依赖(这对于同步通常是不利的).
如果您可以选择使用.NET 4.0,那么您可能需要查看System.Threading.Tasks命名空间中的Task类,因为它提供了一种更好的方法来处理异步处理,取消和等待超时.
Thread.Abort 在调用它的线程中引发 ThreadAbortException
你不应该让异常从你的线程中逃逸——你应该在你的线程对象中进行异常处理。至少应该在线程对象中的代码周围有一个 try\catch 块。