我有一些代码启动了几个线程让它们执行,然后使用while循环来检查当前时间是否超过设置的超时时间,或者是否已经处理了正确的结果数量(通过检查类对象上的int)(在循环之间等待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);
答案 0 :(得分:5)
所以,你真的不应该在线程上使用Sleep方法进行同步。这就是ManualResetEvent等同步类的用途,以及异步编程模型(IAsyncResult实现)。
这里更好的方法是创建一个委托,其中包含要异步运行的方法的签名。然后,将作为异步操作入口点的方法组分配给该委托的实例,并在委托实例上调用BeginInvoke。
从那里开始,你会运行你的循环,期望你在调用BeginInvoke返回的IAsyncResult实现的WaitOne属性返回的WaitHandle上调用AsyncWaitHandle的重载代表。
这将减少对Sleep方法的依赖(通常不利于同步)。
如果您可以选择使用.NET 4.0,那么您可能需要查看Task class中的System.Threading.Tasks namespace,因为它提供了一种更好的方法来处理异步处理,取消,并等待超时。
答案 1 :(得分:3)
Thread.Abort在调用它的线程中引发ThreadAbortException
你不应该让异常从你的线程中逃脱 - 你应该在你的线程对象中进行异常处理。至少应该在线程对象的代码周围有一个try \ catch块。