当前位置:  开发笔记 > 编程语言 > 正文

在C#中有一个很好的方法可以在给定的线程上抛出异常

如何解决《在C#中有一个很好的方法可以在给定的线程上抛出异常》经验,为你挑选了2个好方法。

我想写的代码是这样的:

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 exceptionDictionary = 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

有很多问题可以通过其他机制抛出线程,例如中止线程等,你应该找到另一种方法.

一个例外是一种机制,用于表示某个进程遇到了一些无法处理的特殊情况.您应该尽量避免编写代码,以便使用异常来表示其他人遇到过异常情况.

在你的代码可能引发异常的所有情况下,其他线程很可能不知道如何处理异常.

简而言之,您应该找到一些其他机制来中止您的线程而不是使用异常.

使用事件对象或类似物告诉线程中止其处理,这是最好的方法.



1> angry person..:

有很多问题可以通过其他机制抛出线程,例如中止线程等,你应该找到另一种方法.

一个例外是一种机制,用于表示某个进程遇到了一些无法处理的特殊情况.您应该尽量避免编写代码,以便使用异常来表示其他人遇到过异常情况.

在你的代码可能引发异常的所有情况下,其他线程很可能不知道如何处理异常.

简而言之,您应该找到一些其他机制来中止您的线程而不是使用异常.

使用事件对象或类似物告诉线程中止其处理,这是最好的方法.



2> Orion Edward..:

这不是一个好主意

本文讨论了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可以正常工作.

推荐阅读
pan2502851807
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有