2012-02-07 1 views
0

Я пишу приложение в MonoMac и его имеющим вопрос, где, если я открыть дополнительный диалог, используя этот вызовMonoMac: Возникли проблемы с другими диалогами

var prefForm = new PrefFormController(); 
prefForm.Window.MakeKeyAndOrderFront(mainWindowController); 

приложение заканчивает сбой, если вы переключитесь назад достаточно и дальше от основного диалога и вторичного диалога, или нажатие кнопок приведет к сбою приложения.

Loaded assembly: /Users/michaelmanley/Desktop/NasuTek-StreamDesk/StreamDesk-Cocoa/bin/Debug/StreamDesk.app/Contents/Resources/StreamDesk.exe 
Loaded assembly: /Users/michaelmanley/Desktop/NasuTek-StreamDesk/StreamDesk-Cocoa/bin/Debug/StreamDesk.app/Contents/Resources/StreamDesk.Managed.dll 
Loaded assembly: /Users/michaelmanley/Desktop/NasuTek-StreamDesk/StreamDesk-Cocoa/bin/Debug/StreamDesk.app/Contents/Resources/MonoMac.dll [External] 
Loaded assembly: /Library/Frameworks/Mono.framework/Versions/2.10.8/lib/mono/gac/System.Core/4.0.0.0__b77a5c561934e089/System.Core.dll [External] 
Loaded assembly: /Users/michaelmanley/Desktop/NasuTek-StreamDesk/StreamDesk-Cocoa/bin/Debug/StreamDesk.app/Contents/Resources/Mono.Addins.dll [External] 
Loaded assembly: /Library/Frameworks/Mono.framework/Versions/2.10.8/lib/mono/gac/System/4.0.0.0__b77a5c561934e089/System.dll [External] 
Loaded assembly: /Library/Frameworks/Mono.framework/Versions/2.10.8/lib/mono/gac/System.Xml/4.0.0.0__b77a5c561934e089/System.Xml.dll [External] 
Loaded assembly: __MetadataTypes [External] 
Loaded assembly: __MetadataTypes [External] 
Loaded assembly: /Library/Frameworks/Mono.framework/Versions/2.10.8/lib/mono/gac/Mono.Addins.CecilReflector/0.6.0.0__0738eb9f132ed756/Mono.Addins.CecilReflector.dll [External] 
Thread started: 
Unloaded assembly: /Library/Frameworks/Mono.framework/Versions/2.10.8/lib/mono/gac/Mono.Addins.CecilReflector/0.6.0.0__0738eb9f132ed756/Mono.Addins.CecilReflector.dll 
Unloaded assembly: __MetadataTypes 
Thread finished: 
Thread started: 
Loaded assembly: /Library/Frameworks/Mono.framework/Versions/2.10.8/lib/mono/gac/System.Configuration/4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll [External] 
Thread started: 
Thread started: 
Loaded assembly: /Library/Frameworks/Mono.framework/Versions/2.10.8/lib/mono/gac/Mono.Security/4.0.0.0__0738eb9f132ed756/Mono.Security.dll [External] 
Thread started: 
Thread started: 
Loaded assembly: ObjCImplementations [External] 
Loaded assembly: /Library/Frameworks/Mono.framework/Versions/2.10.8/lib/mono/gac/System.Design/4.0.0.0__b03f5f7f11d50a3a/System.Design.dll [External] 
Loaded assembly: /Library/Frameworks/Mono.framework/Versions/2.10.8/lib/mono/gac/System.Drawing/4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll [External] 
Thread finished: 
Thread started: 
Thread started: 
Thread started: 
Thread started: <---- These pop up every time you go back to the secondary window from the primary window 
Thread started: 
… 
Thread started: 
Thread started: 
Thread started: 
Stacktrace: 

    at (wrapper managed-to-native) MonoMac.AppKit.NSApplication.NSApplicationMain (int,string[]) <IL 0x0009d, 0xffffffff> 
    at MonoMac.AppKit.NSApplication.Main (string[]) [0x00000] in /cvs/monomac/src/AppKit/NSApplication.cs:74 
    at StreamDesk.MainClass.Main (string[]) [0x0000f] in /Users/michaelmanley/Desktop/NasuTek-StreamDesk/StreamDesk-Cocoa/StreamDesk/Main.cs:22 
    at (wrapper runtime-invoke) <Module>.runtime_invoke_void_object (object,intptr,intptr,intptr) <IL 0x00050, 0xffffffff> 

Native stacktrace: 

    0 StreamDesk       0x00094efc mono_handle_native_sigsegv + 284 
    1 StreamDesk       0x00004fe8 mono_sigsegv_signal_handler + 248 
    2 libSystem.B.dylib     0x006db05b _sigtramp + 43 
    3 ???         0xffffffff 0x0 + 4294967295 
    4 AppKit        0x04b80255 -[NSControl sendAction:to:] + 108 
    5 AppKit        0x04b7bd02 -[NSCell _sendActionFrom:] + 169 
    6 AppKit        0x04b7aff9 -[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 1808 
    7 AppKit        0x04bd06ed -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 524 
    8 AppKit        0x04b79a4f -[NSControl mouseDown:] + 812 
    9 AppKit        0x04b77a58 -[NSWindow sendEvent:] + 5549 
    10 AppKit        0x04a9060b -[NSApplication sendEvent:] + 6431 
    11 AppKit        0x04a24253 -[NSApplication run] + 917 
    12 AppKit        0x04a1c289 NSApplicationMain + 574 
    13 ???         0x0d7d9b76 0x0 + 226335606 
    14 ???         0x0d7d9974 0x0 + 226335092 
    15 ???         0x00dee048 0x0 + 14606408 
    16 ???         0x00dee1be 0x0 + 14606782 
    17 StreamDesk       0x0000d282 mono_jit_runtime_invoke + 722 
    18 StreamDesk       0x001a436a mono_runtime_invoke + 170 
    19 StreamDesk       0x001a6f01 mono_runtime_exec_main + 705 
    20 StreamDesk       0x001a6111 mono_runtime_run_main + 929 
    21 StreamDesk       0x00069995 mono_jit_exec + 149 
    22 StreamDesk       0x0006bf13 mono_main + 9587 
    23 StreamDesk       0x00002299 main + 441 
    24 StreamDesk       0x000020a6 start + 54 
    25 ???         0x00000001 0x0 + 1 

Исключение может отличаться, что делает отладку этот вопрос трудно, единственный способ, которым я знаю, что я могу воспроизвести его, перейдя туда и обратно из главного окна, и обратно к вторичному окну, через некоторое время, приложение закончится

Я делаю неправильный способ показать диалог, или это ошибка с самим Mono, но я думал, что Mono может иметь массивную ошибку этого масштаба, где вы не можете отображать другие окна.

ответ

3

Проблема заключается в том, что управляемый объект освобождается до того, как соответствующий собственный объект. Затем собственный объект пытается вызвать метод на управляемом объекте, и приложение выйдет из строя.

Вы, вероятно, может сделать его более воспроизводимым, запустив GC каждый второй:

ThreadPool.QueueUserWorkItem ((v) => 
{ 
    while (true) { 
     Thread.Sleep (1000); 
     GC.Collect (GC.MaxGenerations); 
    } 
}); 

Это где дела идут плохо:

3 ???  0xffffffff 0x0 + 4294967295 
4 AppKit  0x04b80255 -[NSControl sendAction:to:] + 108 

это похоже на проблемы с NSControl (или). Помимо этого трудно сказать, какой объект фактически освобождается от доступной информации. Самый простой способ понять это, вероятно, чтобы объекты были искусственно живыми (например, добавляя их к статическому списку), а затем уменьшайте подмножество объектов, которые вы сохраняете, пока не определите точный экземпляр, вызывающий крах.

Как только вы выяснили, какой объект получает преждевременное освобождение, вы должны убедиться, что GC не освобождает его слишком рано (один из методов заключается в добавлении его в статический список, но лучший подход зависит от каждого дело).

Имейте в виду, что объект не должен быть объектом, который вы явно создаете в своем коде, он также может быть делегатами или обработчиками событий, например.

+0

Да, как показано здесь, делая GC более агрессивным, причиной аварии может случиться по существу, как только будет показано окно, и когда я переместил объекты окна из локальной функциональной переменной в переменную класса, казалось, что GC не преждевременно очистить его, в результате чего больше нет сбоев. Мой другой вопрос: почему GC преждевременно удаляет его, если объект формы и контроллера все еще используется? – DrHouse

+1

Как только функция вернется, переменная в ней больше не сохранит объект. И поскольку управляемый GC не может видеть, к чему относится родной класс (и на данный момент это единственное место, где есть ссылка на него), GC освобождает объект. –