gpt4 book ai didi

c# - C# 中是否有用于在给定线程上引发异常的好方法

转载 作者:可可西里 更新时间:2023-11-01 08:37:32 26 4
gpt4 key购买 nike

我想写的代码是这样的:

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 是否设置了标志,但这会使代码更加复杂。我可以使用更好的机制吗?

这是一个更具体的定期检查示例:

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.
}
}

最佳答案

这不是个好主意

This article talks about ruby's timeout library.跨线程抛出异常。

它解释了做这样的事情是如何从根本上被破坏的。它不仅在 ruby​​ 中被破坏,它在任何跨线程抛出异常的地方都被破坏。

简而言之,可以(并且确实)发生的是:

线程A:

At some random time, throw an exception on thread B:

线程B:

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”标志,并使用它来省去创建异常对象的麻烦。一个 volatile bool 就可以了。

关于c# - C# 中是否有用于在给定线程上引发异常的好方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44656/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com