OnNext当我使用时,观察者抛出错误时我的应用程序终止ObserveOn(Scheduler.ThreadPool).我发现处理这个问题的唯一方法是使用下面的自定义扩展方法(除了确保OnNext永远不会抛出异常).然后确保每个ObserveOn后跟一个ExceptionToError.
public static IObservable<T> ExceptionToError<T>(this IObservable<T> source) {
var sub = new Subject<T>();
source.Subscribe(i => {
try {
sub.OnNext(i);
} catch (Exception err) {
sub.OnError(err);
}
}
, e => sub.OnError(e), () => sub.OnCompleted());
return sub;
}
Run Code Online (Sandbox Code Playgroud)
但是,这感觉不对.有没有更好的方法来处理这个?
例
由于未捕获的异常,此程序崩溃.
class Program {
static void Main(string[] args) {
try {
var xs = new Subject<int>();
xs.ObserveOn(Scheduler.ThreadPool).Subscribe(x => {
Console.WriteLine(x);
if (x % 5 == 0) {
throw new System.Exception("Bang!");
}
}, ex => …Run Code Online (Sandbox Code Playgroud) 我有一个COM可见的.NET类,它暴露事件并从VB6使用.在过去的几天里,我一直试图让这个与regfree COM一起工作,但没有成功.
在regfree模式下从另一个线程触发时,它会抛出异常,因此永远不会执行VB6事件代码.
System.Reflection.TargetException: Object does not match target type.
at System.RuntimeType.InvokeDispMethod(String name, BindingFlags invokeAttr, Object target, Object[] args, Boolean[] byrefModifiers, Int32 culture, String[] namedParameters)
at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)
at Example.Vb6RegFreeCom.IExampleClassEvents.TestEvent()
at Example.Vb6RegFreeCom.ExampleClass.OnTestEvent(Action func) in ExampleClass.cs:line 78
Run Code Online (Sandbox Code Playgroud)
我可以想到两种情况:1)清单缺少与tlb注册相关的内容,或者2)创建新线程时激活上下文丢失.不幸的是,我不知道如何找出是哪种情况,或者甚至可能是由其他东西引起的.
以下是显示我的问题的基本示例.
清单(VB6可执行文件)
<?xml version="1.0" encoding="utf-8"?>
<assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<assemblyIdentity name="VB6COM" …Run Code Online (Sandbox Code Playgroud) ValueTuple.IComparable.CompareTo(Object)的文档说它返回:
0如果other是ValueTuple实例; 否则,1如果other为null.
这使得IComparable实现看起来似乎毫无用处,除了可能没有破坏可能期望实现接口的代码.旧的引用Tuple类确实遵循标准实现(尽管它可能仅在项支持时才有效IComparable).
文档IComparable说明了可以对类型进行排序,但情况并非如此ValueTuple:
此接口由可以对其值进行排序或排序的类型实现.它要求实现类型定义了一个方法,的CompareTo,指示当前实例的排序顺序的位置是否是前,后,或相同的相同类型的第二个目的.(......)
CompareTo方法的实现必须返回具有三个值之一的Int32,如下表所示.
小于零当前实例位于排序顺序中CompareTo方法指定的对象之前.
零此当前实例出现在排序顺序中与CompareTo方法指定的对象相同的位置.
大于零此当前实例遵循排序顺序中CompareTo方法指定的对象.
所以我的问题是:
ValueTuple实现CompareTo呢?IComparable即使它不支持有意义的排序?我在2年前创建了一个WiX文件,其中包含对特征操作值5的检查.
值5应指示重新安装/修复,但我找不到任何WiX/msi文档.我发现的页面最多可达4,就像在MSDN上一样.
<!-- always install if feature will be installed/reinstalled local -->
<Custom Action="MyInstallAction" After="InstallFiles">
<![CDATA[(&ca_feature=3) OR (&ca_feature=5)]]> <!-- <<< HERE -->
</Custom>
<!-- remove if feature is going from local to absent -->
<Custom Action="MyUninstallAction" After="RemoveRegistryValues">
<![CDATA[(&ca_feature=2) AND (!ca_feature=3)]]>
</Custom>
<Custom Action="UninstallUsbBusDriver" After="RemoveRegistryValues">
<![CDATA[(&ca_feature=2) AND (!ca_feature=3)]]>
</Custom>
Run Code Online (Sandbox Code Playgroud)
我开始怀疑是否曾经使用过5值,但是我再次发现很难相信我没有理由把它放在那里.