fry*_*bob 11 c# multithreading exception
我想写的代码是这样的:
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.
}
}
Run Code Online (Sandbox Code Playgroud)
我知道我可以让线程B以线程安全的方式定期检查线程A是否设置了一个标志,但这会使代码更复杂.有没有更好的机制可供我使用?
以下是定期检查的更加充实的示例:
Dictionary<Thread, Exception> exceptionDictionary = new Dictionary<Thread, Exception>();
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.
}
}
Run Code Online (Sandbox Code Playgroud)
ang*_*son 10
有很多问题可以通过其他机制抛出线程,例如中止线程等,你应该找到另一种方法.
一个例外是一种机制,用于表示某个进程遇到了一些无法处理的特殊情况.您应该尽量避免编写代码,以便使用异常来表示其他人遇到过异常情况.
在你的代码可能引发异常的所有情况下,其他线程很可能不知道如何处理异常.
简而言之,您应该找到一些其他机制来中止您的线程而不是使用异常.
使用事件对象或类似物告诉线程中止其处理,这是最好的方法.
Ori*_*rds 10
这不是一个好主意
本文讨论了ruby的超时库.它会在线程之间抛出异常.
它解释了如何从根本上打破这样的事情.它不仅仅是在ruby中被打破,它在任何可以跨线程抛出异常的地方都被破坏了.
简而言之,可以(并且确实)发生的是:
ThreadA中:
At some random time, throw an exception on thread B:
Run Code Online (Sandbox Code Playgroud)
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();
}
Run Code Online (Sandbox Code Playgroud)
您的"定期检查"示例很好,因为您实际上并没有跨线程抛出异常.
你只是设置了一个标志,上面写着"下次你看这个标志时会抛出一个异常",这很好,因为它不会受到"可以在你的捕获中间抛出或最终阻塞"的问题.
但是,如果您要这样做,您也可以设置一个"exitnow"标志,并使用它并节省创建异常对象的麻烦.一个挥发性的bool可以正常工作.