反应式扩展在Windows Phone上存在Bug

114

使用VS 2012编译,项目类型为WP 8.0。如果没有附加调试器,则以下代码将失败。

不知何故,如果没有附加调试器,编译器的优化会破坏Crash()内部的代码-请参见代码中的注释。

Lumia 1520(8.1)Lumia 630(8.0)上进行了测试。

有任何想法是为什么会发生这种情况吗?

public partial class MainPage : PhoneApplicationPage
{
    public MainPage()
    {
        InitializeComponent();
        Button.Tap += (sender, args) => new A<B, string>(new B(), "string").Crash();
    }
}
public class B
{
    public void Foo<T>(T val) { }
}
public class A<T1, T2> where T1 : B
{
    private T1 _t1;
    private T2 _t2;
    public A(T1 t1, T2 t2)
    {
        _t2 = t2;
        _t1 = t1;
    }
    public void Crash()
    {
        var obs = Observable.Return(_t2);
        obs.Subscribe(result =>
        {
            //CLR is expecting T2 to be System.String here,
            //but somehow, after passing through Observable
            //T2 here is not a string, it's A<T1, T2>

            new List<T2>().Add(result);
        });
        //Will run normally if commented
        _t1.Foo(new object());
    }
}

6
似乎是编译器错误,而不是 Rx 错误。您尝试过使用 ILSpy 或 .NET Reflector 来检查生成的 IL 吗? - Brandon
8
我建议使用Observable.Return<T2>(_t2);,而不是让编译器来决定类型。这里可能存在错误,虽然可能性很小。 - cwharris
6
我在Windows Phone上使用Rx时遇到了很多问题。对我来说,它可以编译,但实际尝试调用包含类时会抛出“MethodNotFoundException”。升级到VS Update 2的发行版本后,问题得以解决。我仍然不知道实际上出了什么问题,但请确保您正在使用最新的更新版本。显然我们的问题有点不同,但这可能会有所帮助。 - Matthew Haugen
5
这个问题是什么 - “有任何想法吗?” - 你只是想知道如何让它停止崩溃吗? - Tim Lovell-Smith
1
Akbar Ali是正确的 - .Foo()调用没有参数化,这迫使它推断类型。如果您传递的参数是对象,您不能指望它知道它是<string>。 - Kamen
显示剩余5条评论
1个回答

1
 _t1.Foo<type>(type);

你缺少类型声明。编译器在猜测(并且猜错了)。严格按类型定义一切,程序就能运行。


这不是什么线索,你可以自己实现IObserver和IObservable,一切都会正常工作。 - Yuriy Naydenov
看起来调试器正在与编译器建立连接,而调试器也需要所有变量都是严格类型的。调试器猜测正确,编译器在某种程度上从中获取线索。 调试器修复问题的原因并不重要,根本原因已经找到了。 - Japes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接