Błąd rozszerzeń reaktywnych w systemie Windows Phone

114

Skompilowany z VS 2012typem projektu WP 8.0następujący kod zakończy się niepowodzeniem, jeśli debuger nie jest dołączony.

W jakiś sposób, jeśli debugger nie jest dołączony, optymalizacje kompilatora niszczą kod wewnątrz Crash()- zobacz komentarze w kodzie.

Przetestowano na Lumii 1520 (8.1) i Lumii 630 (8.0) .

Jakieś pomysły, dlaczego tak się dzieje?

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());
    }
}
Yuriy Naydenov
źródło
6
Wygląda na błąd kompilatora, a nie błąd Rx. Czy próbowałeś użyć ILSpy lub .NET Reflector do zbadania wygenerowanego IL?
Brandon,
8
Spróbowałbym użyć Observable.Return<T2>(_t2);zamiast pozostawiać kompilatorowi wybór tutaj typu. Może być w tym błąd. To prawda, to długa szansa.
cwharris
6
Miałem mnóstwo problemów z Rx na Windows Phone. Dla mnie kompilowałby się, a następnie wyrzucał, MethodNotFoundExceptiongdy faktycznie próbowałem wywołać klasę zawierającą. Dla mnie aktualizacja do wersji VS Update 2 działała. Nadal nie mam pojęcia, co było tak naprawdę nie tak, ale upewnij się, że używasz najnowszych aktualizacji we wszystkim. Oczywiście nasze problemy są trochę inne, ale to może pomóc w udzieleniu wskazówek.
Matthew Haugen,
5
Jakie jest pytanie - „jakieś pomysły?” - czy chcesz tylko wiedzieć, jak sprawić, by przestał się zawieszać?
Tim Lovell-Smith
1
może być spowodowane tym, że _t1.Foo <brak tutaj typu> (i tutaj też);
akbar ali

Odpowiedzi:

1
 _t1.Foo<type>(type);

Brakuje deklaracji typu. Kompilator zgaduje (i zgaduje źle). Ściśle wpisz wszystko i powinno działać.

Japes
źródło
To nie jest wskazówka, możesz samodzielnie zaimplementować IObserver i IObservable i wszystko będzie działać dobrze.
Yuriy Naydenov
Wygląda na to, że debugger tworzy połączenie z kompilatorem, a debugger również potrzebuje ścisłego wpisania wszystkich zmiennych. Debugger zgaduje poprawnie, a kompilator w jakiś sposób pobiera z niego zapytania. Naprawdę nie ma znaczenia, dlaczego debugger rozwiązuje problem, znaleziono główną przyczynę.
Japes