【问题标题】:STA thread exception propagationSTA 线程异常传播
【发布时间】:2011-05-02 21:25:52
【问题描述】:

我有一个必须作为 STA 运行的函数,并且我想将其异常传播到调用线程。这里是:

public void ExceptionBePropagatedThroughHere()
{
  Thread thread = new Thread(TheSTAThread);
  thread.SetApartmentState(ApartmentState.STA);
  thread.Start();
  thread.Join();
}

public void MainFunction()
{
  try
  {
    ExceptionBePropagatedThroughHere();
  }
  catch(Exception e)
  {
     //will not hit here
  }
}

将 STA 属性放在“MainFunction”上不是一个选项。 我注意到如果我使用的是任务,在任务连接上尝试捕获会将异常传播到调用线程,但是我不能将任务指定为 STA。

问题是如何将作为 STA 运行的异常传播到上例中的“MainFunction”?

提前致谢。

【问题讨论】:

  • 只需将异常对象存储在类字段中即可。您不能随意创建一个 STA 线程来让 COM 满意,您调用的对象必须在同一个线程上创建。在线程上泵送消息循环是许多单线程 COM 服务器所依赖的其他东西。

标签: c# multithreading exception


【解决方案1】:

我听从了 Hans 的建议,解决方案如下所示,不需要触发任何事件。

private Exception _exception;
public void ExceptionBePropagatedThroughHere()
{
  Thread thread = new Thread(TheSTAThread);Thread thread = new Thread(TheSTAThread);
  thread.SetApartmentState(ApartmentState.STA);
  thread.Start();
  thread.Join();
  if(_exception != null)
    throw new Exception("STA thread failed", _exception);
}

private void TheSTAThread()
{
  try
  {
    //do the stuff
  }
  catch (Exception ex)
  {
    _exception = ex;
  }
}
public void MainFunction()
{
  try
  {
    ExceptionBePropagatedThroughHere();
  }
  catch(Exception e)
  {
     //will not hit here
  }
}

【讨论】:

  • 记住在启动线程时清除异常,否则第二次运行时,您将得到第一次捕获的任何异常被重新抛出。另请注意,这显然只有在只有 1 个 TheSTAThread 实例运行时才有效。
【解决方案2】:

您需要在等待期间保持消息泵的正常运行。 Thread.Join 不是您可以使用的选项,因为它会阻塞您的线程,直到另一个线程终止。 一个非常简单的消息泵是您创建两个事件,称为 StaThreadExited 和 StaThreadExceptionEvent。您可以在事件数组上使用 WaitHandle.WaitAny。如果这是一个异常事件,您可以从例如获取它。一个共享变量并在您自己的线程中重新抛出它。前段时间我什至在这里发布了code

你的, 阿洛伊斯克劳斯

【讨论】:

  • Thread.Join() 在 STA 线程上调用时会抽出一个消息循环。显然不是,如果是,他就不必跳过这个圈了。
  • 堆栈跟踪以这种方式消失了,它被更改为新抛出的点。
  • 发现可以通过将旧异常放入内部异常来重建新异常,谢谢。
【解决方案3】:

不管线程是 STA 还是 MTA。其中未捕获的异常将使您的应用程序崩溃。你不能把它扔给创建你行为不端的线程的线程,除非你设计一个手动的方法:比如捕捉,把它存储在某个地方,然后通知主线程有一个错误

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-15
    • 2011-11-08
    • 1970-01-01
    • 2012-07-17
    • 2010-09-18
    • 1970-01-01
    • 1970-01-01
    • 2012-06-28
    相关资源
    最近更新 更多