我想写的代码是这样的:
void MethodOnThreadA() { for (;;) { // Do stuff if (ErrorConditionMet) ThrowOnThread(threadB, new MyException(...)); } } void MethodOnThreadB() { try { for (;;) { // Do stuff } } catch (MyException ex) { // Do the right thing for this exception. } }
我知道我可以让线程B以线程安全的方式定期检查线程A是否设置了一个标志,但这会使代码更复杂.有没有更好的机制可供我使用?
以下是定期检查的更加充实的示例:
DictionaryexceptionDictionary = new Dictionary (); void ThrowOnThread(Thread thread, Exception ex) { // the exception passed in is going to be handed off to another thread, // so it needs to be thread safe. lock (exceptionDictionary) { exceptionDictionary[thread] = ex; } } void ExceptionCheck() { lock (exceptionDictionary) { Exception ex; if (exceptionDictionary.TryGetValue(Thread.CurrentThread, out ex)) throw ex; } } void MethodOnThreadA() { for (;;) { // Do stuff if (ErrorConditionMet) ThrowOnThread(threadB, new MyException(...)); } } void MethodOnThreadB() { try { for (;;) { // Do stuff ExceptionCheck(); } } catch (MyException ex) { // Do the right thing for this exception. } }
angry person.. 10
有很多问题可以通过其他机制抛出线程,例如中止线程等,你应该找到另一种方法.
一个例外是一种机制,用于表示某个进程遇到了一些无法处理的特殊情况.您应该尽量避免编写代码,以便使用异常来表示其他人遇到过异常情况.
在你的代码可能引发异常的所有情况下,其他线程很可能不知道如何处理异常.
简而言之,您应该找到一些其他机制来中止您的线程而不是使用异常.
使用事件对象或类似物告诉线程中止其处理,这是最好的方法.
有很多问题可以通过其他机制抛出线程,例如中止线程等,你应该找到另一种方法.
一个例外是一种机制,用于表示某个进程遇到了一些无法处理的特殊情况.您应该尽量避免编写代码,以便使用异常来表示其他人遇到过异常情况.
在你的代码可能引发异常的所有情况下,其他线程很可能不知道如何处理异常.
简而言之,您应该找到一些其他机制来中止您的线程而不是使用异常.
使用事件对象或类似物告诉线程中止其处理,这是最好的方法.
这不是一个好主意
本文讨论了ruby的超时库.它会在线程之间抛出异常.
它解释了如何从根本上打破这样的事情.它不仅仅是在ruby中被打破,它在任何可以跨线程抛出异常的地方都被破坏了.
简而言之,可以(并且确实)发生的是:
ThreadA中:
At some random time, throw an exception on thread B:
ThreadB:
try { //do stuff } finally { CloseResourceOne(); // ThreadA's exception gets thrown NOW, in the middle // of our finally block and resource two NEVER gets closed. // Obviously this is BAD, and the only way to stop is to NOT throw // exceptions across threads CloseResourceTwo(); }
您的"定期检查"示例很好,因为您实际上并没有跨线程抛出异常.
你只是设置了一个标志,上面写着"下次你看这个标志时会抛出一个异常",这很好,因为它不会受到"可以在你的捕获中间抛出或最终阻塞"的问题.
但是,如果您要这样做,您也可以设置一个"exitnow"标志,并使用它并节省创建异常对象的麻烦.一个挥发性的bool可以正常工作.