Xamarin.Mac 事件和线程似乎不能协同工作



我用Xamarin有很多困难。

基本上所有我想做的是POST和抓取一些JSON到/从一个web服务器,然后调用一个事件,气泡通过委托(最终将是一个)UI更改事件(目前它只是一个调试。writeline调用).

我有两个PCL库,一个是"核心",另一个是核心引用的库,一个WPF应用程序和一个OS X应用程序- WPF应用程序工作良好。我还使用了MVVMCross

起初,我尝试使用一个预先存在的类,我使用HTTPWebRequest,它工作得很好,第一个按钮点击(触发这个调用)。在第二个按钮上点击OS X应用程序崩溃。我试着切换到HttpClient,没有骰子。

在阅读了这个线程:https://bugzilla.xamarin.com/show_bug.cgi?id=19906之后,我尝试了使用接口将OS X应用程序的HTTP类切换到NSUrlConnection的本地实现。

现在这是我发现自己的情况:如果我有一个NSUrlConnection异步请求与一个匿名函数传递给它,它的工作永远点击后点击如果我把它拿出来,并调用FireEvent()函数,它只是引发事件(这可能会引发更多的事件链),然后它永远工作,点击后点击如果我同时拥有匿名异步函数和FireEvent,那么在第三次点击触发该函数的按钮时,它会引发本机崩溃。

如果我取出所有异步的东西,它会工作得很好,但这不是理想的。

任何想法?我已经无计可施了。

        public void ExecuteAsync() 
    {
        var request = new NSUrlRequest(new NSUrl("http://www.example.com"));
        asyncRunning = true;
        NSUrlConnection.SendAsynchronousRequest(request, NSOperationQueue.MainQueue, delegate(NSUrlResponse response, NSData data, NSError error) {
        var responseStr = data.ToString();
            var blah = new HttpResponseCompleteEventArgs("{TESTJSONThatIveRemovedForReadability}");
            System.Diagnostics.Debug.WriteLine("Inside IsMainThread: " + NSThread.IsMain.ToString());
            response.InvokeOnMainThread ( delegate {
                FireEvent(blah);
                System.Diagnostics.Debug.WriteLine("Inside IsMainThread invoke: " + NSThread.IsMain.ToString());
            });

        });
        System.Diagnostics.Debug.WriteLine("Outside IsMainThread: " + NSThread.IsMain.ToString());

    }

和崩溃

Stacktrace:
  at <unknown> <0xffffffff>
  at (wrapper managed-to-native) MonoMac.AppKit.NSApplication.NSApplicationMain (int,string[]) <IL 0x0009d, 0xffffffff>
  at MonoMac.AppKit.NSApplication.Main (string[]) [0x00041] in /Users/builder/data/lanes/xamcore-lion-1.8-branch/b8b75fd4/source/xamcore/src/AppKit/NSApplication.cs:105
  at FreshlySqueezed.Mac.MainClass.Main (string[]) [0x00007] in /Users/blah/Development/Development/FreshlySqueezed/FreshlySqueezed.Mac/Main.cs:14
  at (wrapper runtime-invoke) <Module>.runtime_invoke_void_object (object,intptr,intptr,intptr) <IL 0x00050, 0xffffffff>
Native stacktrace:

Debug info from gdb:
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
^D
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quit
^D
quProcess 2693 stopped
* thread #1: tid = 0x1e2f7, 0x91b0cfed libsystem_kernel.dylib`__wait4 + 5, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
  thread #2: tid = 0x1e30e, 0x91b0d992 libsystem_kernel.dylib`kevent64 + 10, queue = 'com.apple.libdispatch-manager'
  thread #3: tid = 0x1e30f, 0x91b0d046 libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #4: tid = 0x1e310, 0x91b0d046 libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #5: tid = 0x1e311, 0x91b0d046 libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #6: tid = 0x1e314, 0x91b07fb6 libsystem_kernel.dylib`semaphore_wait_trap + 10
  thread #7: tid = 0x1e315, 0x91b0ca26 libsystem_kernel.dylib`__recvfrom + 10
  thread #8: tid = 0x1e32c, 0x91b07f7a libsystem_kernel.dylib`mach_msg_trap + 10
  thread #9: tid = 0x1e32e, 0x91b0d046 libsystem_kernel.dylib`__workq_kernreturn + 10
(lldb) quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit^D
qu* thread #1: tid = 0x1e2f7, 0x91b0cfed libsystem_kernel.dylib`__wait4 + 5, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
  * frame #0: 0x91b0cfed libsystem_kernel.dylib`__wait4 + 5
    frame #1: 0x92c46ec5 libsystem_c.dylib`waitpid$UNIX2003 + 48
    frame #2: 0x018ab5f9 libmono-2.0.dylib`mono_handle_native_sigsegv(signal=11, ctx=0x006e1fe0) + 489 at mini-exceptions.c:2305
    frame #3: 0x018fd9d5 libmono-2.0.dylib`mono_arch_handle_altstack_exception(sigctx=0x006e1fe0, fault_addr=0x608962a8, stack_ovf=0) + 149 at exceptions-x86.c:1170
    frame #4: 0x01804351 libmono-2.0.dylib`mono_sigsegv_signal_handler(_dummy=11, info=0x006e1fa0, context=0x006e1fe0) + 369 at mini.c:6842
    frame #5: 0x94fd1deb libsystem_platform.dylib`_sigtramp + 43
  thread #2: tid = 0x1e30e, 0x91b0d992 libsystem_kernel.dylib`kevent64 + 10, queue = 'com.apple.libdispatch-manager'
    frame #0: 0x91b0d992 libsystem_kernel.dylib`kevent64 + 10
    frame #1: 0x9a415899 libdispatch.dylib`_dispatch_mgr_invoke + 238
    frame #2: 0x9a415532 libdispatch.dylib`_dispatch_mgr_thread + 52
  thread #3: tid = 0x1e30f, 0x91b0d046 libsystem_kernel.dylib`__workq_kernreturn + 10
    frame #0: 0x91b0d046 libsystem_kernel.dylib`__workq_kernreturn + 10
    frame #1: 0x91cfbdcf libsystem_pthread.dylib`_pthread_wqthread + 372
  thread #4: tid = 0x1e310, 0x91b0d046 libsystem_kernel.dylib`__workq_kernreturn + 10
    frame #0: 0x91b0d046 libsystem_kernel.dylib`__workq_kernreturn + 10
    frame #1: 0x91cfbdcf libsystem_pthread.dylib`_pthread_wqthread + 372
  thread #5: tid = 0x1e311, 0x91b0d046 libsystem_kernel.dylib`__workq_kernreturn + 10
    frame #0: 0x91b0d046 libsystem_kernel.dylib`__workq_kernreturn + 10
    frame #1: 0x91cfbdcf libsystem_pthread.dylib`_pthread_wqthread + 372
  thread #6: tid = 0x1e314, 0x91b07fb6 libsystem_kernel.dylib`semaphore_wait_trap + 10
    frame #0: 0x91b07fb6 libsystem_kernel.dylib`semaphore_wait_trap + 10
    frame #1: 0x01a1891e libmono-2.0.dylib`mono_sem_wait(sem=<unavailable>, alertable=<unavailable>, sem=0x01b1ac20, alertable=1) + 30 at mono-semaphore.c:121
    frame #2: 0x019c43ea libmono-2.0.dylib`finalizer_thread(unused=0x00000000) + 74 at gc.c:1073
    frame #3: 0x0199c654 libmono-2.0.dylib`start_wrapper [inlined] start_wrapper_internal(data=0x00193bd0) + 442 at threads.c:647
    frame #4: 0x0199c49a libmono-2.0.dylib`start_wrapper(data=0x00193bd0) + 26 at threads.c:692
    frame #5: 0x01a1de1d libmono-2.0.dylib`inner_start_thread(arg=0xbffff2c0) + 253 at mono-threads-posix.c:94
    frame #6: 0x01a3eebd libmono-2.0.dylib`GC_start_routine(arg=0x006e2f60) + 93 at pthread_support.c:1502
    frame #7: 0x91cfa5fb libsystem_pthread.dylib`_pthread_body + 144
    frame #8: 0x91cfa485 libsystem_pthread.dylib`_pthread_start + 130
  thread #7: tid = 0x1e315, 0x91b0ca26 libsystem_kernel.dylib`__recvfrom + 10
    frame #0: 0x91b0ca26 libsystem_kernel.dylib`__recvfrom + 10
    frame #1: 0x92c470c9 libsystem_c.dylib`recv$UNIX2003 + 54
    frame #2: 0x018d58c0 libmono-2.0.dylib`socket_transport_recv(buf=0xb039aeed, len=11) + 160 at debugger-agent.c:1085
    frame #3: 0x018d1c8d libmono-2.0.dylib`debugger_thread(arg=0x00000000) + 21485 at debugger-agent.c:1475
    frame #4: 0x01a1de1d libmono-2.0.dylib`inner_start_thread(arg=0xbffff2c0) + 253 at mono-threads-posix.c:94
    frame #5: 0x01a3eebd libmono-2.0.dylib`GC_start_routine(arg=0x006e2f60) + 93 at pthread_support.c:1502
    frame #6: 0x91cfa5fb libsystem_pthread.dylib`_pthread_body + 144
    frame #7: 0x91cfa485 libsystem_pthread.dylib`_pthread_start + 130
  thread #8: tid = 0x1e32c, 0x91b07f7a libsystem_kernel.dylib`mach_msg_trap + 10
    frame #0: 0x91b07f7a libsystem_kernel.dylib`mach_msg_trap + 10
    frame #1: 0x91b0716c libsystem_kernel.dylib`mach_msg + 68
    frame #2: 0x9bea0bf9 CoreFoundation`__CFRunLoopServiceMachPort + 169
    frame #3: 0x9bea01d1 CoreFoundation`__CFRunLoopRun + 1393
    frame #4: 0x9be9f9ea CoreFoundation`CFRunLoopRunSpecific + 394
    frame #5: 0x9be9f84b CoreFoundation`CFRunLoopRunInMode + 123
    frame #6: 0x90de9b88 AppKit`_NSEventThread + 283
    frame #7: 0x91cfa5fb libsystem_pthread.dylib`_pthread_body + 144
    frame #8: 0x91cfa485 libsystem_pthread.dylib`_pthread_start + 130
  thread #9: tid = 0x1e32e, 0x91b0d046 libsystem_kernel.dylib`__workq_kernreturn + 10
    frame #0: 0x91b0d046 libsystem_kernel.dylib`__workq_kernreturn + 10
    frame #1: 0x91cfbdcf libsystem_pthread.dylib`_pthread_wqthread + 372
Executing commands in '/tmp/mono-gdb-commands.J45EfM'.
(lldb)  process attach --pid 2693
Process 2693 stopped

有人知道吗?我一头雾水。

谢谢

所以经过几个小时的挠头,我似乎偶然发现了解决方案。

从一开始,我就怀疑这与垃圾收集有关,或者事件失去了它的绑定,因为在我的任何代码被点击第三次后,应用程序崩溃了,从阅读Xamarin/OS X的其他stackoverflow问题,我的症状听起来像一个过度渴望的垃圾收集器。

所以一开始我以为每次我从web服务器得到响应时都会引发一个事件,事件已经冒泡到ViewModel,所以本质上它在OSX项目中冒泡到ViewController。目的是尝试使用此事件在每次单击后重新绑定按钮绑定-但是我尝试使用空事件处理程序运行它,并且我发现它修复了初始问题!

尽管ViewController已经通过这个有一个对ViewModel的引用。ViewModel,似乎OS X/XamMac是过于急于和处置ViewModel,因此把应用程序到它的膝盖。有趣的是,我只发现添加和处理一个事件来解决这个问题,试图分配这个。对另一个类变量的ViewModel没有影响。

下面是修复它的代码:

在视图模型中我添加了这个:

public event System.EventHandler GoCommandFinished;
public void CallbackFromWebRequest(SqueezeBase value){
                System.Diagnostics.Debug.WriteLine("hmmm");
            Hello = "whey?" + x;
            if (GoCommandFinished != null) {
                GoCommandFinished (null, null);
            }
        }

在OS X侧的视图控制器中我将这个添加到ViewDidLoad:

((FirstViewModel)this.ViewModel).GoCommandFinished += GoCommandFinished;

,然后创建一个空函数来处理:

private void GoCommandFinished(object sender, EventArgs e){
        }

和volia !我很想知道一种更干净的方法来解决这个问题,因为这对我来说感觉很粗糙……但现在,我不在乎,它有效!但如果有Xamarin的人能解释一下如何更优雅地平息垃圾收集,那就太好了!

谢谢

最新更新