C#:将类型化异常发送到另一个进程 -> 转换为基本异常?
C#: Sending typed exceptions to another process -> transform to base exception?
我正在开发一个由多个服务(进程)组成的分布式系统,这些服务(进程)通过消息代理(服务总线)协同工作。其中一些服务对时间非常敏感,因此我们想到了使用总线将异常传播到一个服务,该服务将用作记录(到 database/on 磁盘)所有其他服务异常的中心点为了不在我们的服务中造成延迟,因为我们知道发送消息比在磁盘上写入更快。因此,我使用 NLog 创建了一个新目标,用于在总线上发送异常并将所有服务异常处理重定向到它。
它适用于基本的框架异常,但当然有些异常可能是非常复杂的对象。当使用不同的库时,不仅某些异常不可序列化(例如:IronPython),而且更重要的是我们的 ExceptionLogger 服务没有引用每个其他端点使用的每个外部 dll,因此它无法实例化类型化异常。
这里有一些想法,我必须解决我的问题,但 none 工作:
让异常记录器服务引用其他服务使用的每个 dll。在我看来,这并不干净,有点矫枉过正,而且仍然不处理甚至无法序列化并在总线上传递的异常情况。
创建一个不从异常继承的自定义 class 以仅传递数据(此处为 Antony Booth 方法:How to serialize an Exception object in C#?)。问题在于,当我在我的异常记录器端点上收到此 class 的实例并想要触发日志时,我无法从中创建新的 Exception() 来创建 NLog LogEventInfo 对象。
在将特殊类型的异常发送到总线上之前将其转换为基本的本机异常类型。这样,我丢失了一些信息,但我会保留 Message、Stacktrace 和 InnerException 堆栈,这几乎是我需要的一切。不幸的是,我没有找到一种方法来做到这一点,我认为这是不可能的。
这让我质疑整个想法的相关性,我只是走错了路吗?
选项 4。创建一个 Exception
程序集来存储您组织内的所有自定义异常类型,并在所有其他服务中引用该程序集。它是异常的集中存储。
[Serializable]
public sealed class SerializableException : Exception
{
public SerializableException()
{
}
public SerializableException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
public SerializableException(Exception exception)
: base(exception.Message, exception.InnerException == null ? null : new SerializableException(exception.InnerException))
{
_data = exception.Data;
HelpLink = exception.HelpLink;
HResult = exception.HResult;
Source = exception.Source;
_stackTrace = exception.StackTrace;
}
public override IDictionary Data { get { return _data; } }
public override string StackTrace { get { return _stackTrace; } }
private readonly IDictionary _data;
private readonly string _stackTrace;
}
我正在开发一个由多个服务(进程)组成的分布式系统,这些服务(进程)通过消息代理(服务总线)协同工作。其中一些服务对时间非常敏感,因此我们想到了使用总线将异常传播到一个服务,该服务将用作记录(到 database/on 磁盘)所有其他服务异常的中心点为了不在我们的服务中造成延迟,因为我们知道发送消息比在磁盘上写入更快。因此,我使用 NLog 创建了一个新目标,用于在总线上发送异常并将所有服务异常处理重定向到它。
它适用于基本的框架异常,但当然有些异常可能是非常复杂的对象。当使用不同的库时,不仅某些异常不可序列化(例如:IronPython),而且更重要的是我们的 ExceptionLogger 服务没有引用每个其他端点使用的每个外部 dll,因此它无法实例化类型化异常。
这里有一些想法,我必须解决我的问题,但 none 工作:
让异常记录器服务引用其他服务使用的每个 dll。在我看来,这并不干净,有点矫枉过正,而且仍然不处理甚至无法序列化并在总线上传递的异常情况。
创建一个不从异常继承的自定义 class 以仅传递数据(此处为 Antony Booth 方法:How to serialize an Exception object in C#?)。问题在于,当我在我的异常记录器端点上收到此 class 的实例并想要触发日志时,我无法从中创建新的 Exception() 来创建 NLog LogEventInfo 对象。
在将特殊类型的异常发送到总线上之前将其转换为基本的本机异常类型。这样,我丢失了一些信息,但我会保留 Message、Stacktrace 和 InnerException 堆栈,这几乎是我需要的一切。不幸的是,我没有找到一种方法来做到这一点,我认为这是不可能的。
这让我质疑整个想法的相关性,我只是走错了路吗?
选项 4。创建一个 Exception
程序集来存储您组织内的所有自定义异常类型,并在所有其他服务中引用该程序集。它是异常的集中存储。
[Serializable]
public sealed class SerializableException : Exception
{
public SerializableException()
{
}
public SerializableException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
public SerializableException(Exception exception)
: base(exception.Message, exception.InnerException == null ? null : new SerializableException(exception.InnerException))
{
_data = exception.Data;
HelpLink = exception.HelpLink;
HResult = exception.HResult;
Source = exception.Source;
_stackTrace = exception.StackTrace;
}
public override IDictionary Data { get { return _data; } }
public override string StackTrace { get { return _stackTrace; } }
private readonly IDictionary _data;
private readonly string _stackTrace;
}