Xamarin.Mac事件和线程似乎不能一起工作

时间:2014-07-08 21:18:46

标签: c# multithreading xamarin mvvmcross xamarin.mac

目前我对Xamarin.Mac有很多困难。

基本上我想要做的就是POST和从网络服务器获取一些JSON,然后调用一个事件,通过代理冒泡到(最终会是什么)UI更改事件(此刻它只是一个debug.writeline call。。

我有两个PCL库,一个是'核心',另一个是核心引用的库,一个WPF应用程序和一个OS X应用程序 - WPF应用程序正常工作。我也在使用MVVMCross。

首先,我尝试使用一个使用HTTPWebRequest的预先存在的类,它工作正常,用于第一次按键点击(触发此调用)。在第二个按钮上单击OS X应用程序崩溃。我尝试切换到HttpClient,没有骰子。

读完这个帖子后:https://bugzilla.xamarin.com/show_bug.cgi?id=19906我试过,使用接口将OS X应用程序的HTTP类切换到NSUrlConnection的本机实现。

现在这是我发现自己的情况: 如果我有一个带有匿名函数的NSUrlConnection ASync请求,它会在点击后永久点击 如果我把它取出并调用一个FireEvent()函数,该函数只会引发事件(这可能会在链中产生更多事件),那么它将永远有效,点击后单击 如果我同时拥有带有匿名函数的ASync和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

任何人都有任何想法?我很难过。

由于

1 个答案:

答案 0 :(得分:0)

因此,经过几个小时的搔痒,我似乎偶然发现了解决方案。

从早期开始,我怀疑这与垃圾收集有关,或者在第三次点击按钮之后,当我的任何代码被点击之前应用程序崩溃,以及读取其他stackoverflow问题时,会失去绑定的事件使用Xamarin / OS X,我的症状听起来类似于过度热衷的垃圾收集器。

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

因此,尽管ViewController已经通过this.ViewModel引用了ViewModel,但似乎OS X / XamMac过于急切并且处理了ViewModel,因此将App带到了它的膝盖。有趣的是,我只发现添加和处理事件来解决这个问题,尝试将this.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的任何人都可以解释如何更加优雅地平息垃圾收集,那就太棒了!

由于