C# Xamarin.Mac NSThread.Start()堆栈溢出
我有一个相当复杂的Xamarin.Mac应用程序。事实上,它是一个windows窗体应用程序,但我们使用Mono实现Mac与本机Mac GUI的兼容性。我们的一个业务逻辑组件涉及使用FSWatcher监视文件系统的更改。不幸的是,Mac上的FSWatcher严重崩溃,我们只能通过Xamarin.Mac使用本机FSEvents API 在业务逻辑的深处,我有一个名为CBFileSystemWatcher的自定义类,它包装了.NET FSWatcher,并且在mac上提供了预期业务逻辑的FSWatcher和mac上的FSEvents之间的适配器。在这个兼容性类中,我有C# Xamarin.Mac NSThread.Start()堆栈溢出,c#,macos,mono,xamarin,C#,Macos,Mono,Xamarin,我有一个相当复杂的Xamarin.Mac应用程序。事实上,它是一个windows窗体应用程序,但我们使用Mono实现Mac与本机Mac GUI的兼容性。我们的一个业务逻辑组件涉及使用FSWatcher监视文件系统的更改。不幸的是,Mac上的FSWatcher严重崩溃,我们只能通过Xamarin.Mac使用本机FSEvents API 在业务逻辑的深处,我有一个名为CBFileSystemWatcher的自定义类,它包装了.NET FSWatcher,并且在mac上提供了预期业务逻辑的FSWatc
private FSEventStream eventStream;
//...
this.eventStream.ScheduleWithRunLoop (NSRunLoop.Main);
它在主运行循环上调度文件系统事件。不幸的是,这意味着GUI会阻止FS事件处理,因此,如果模式对话框打开,例如,FS事件会突然停止处理
我的想法是为FS事件调度创建一个新的runloop,我认为它如下所示
NSThread.Start(()=>{
// Some other code
this.eventStream.ScheduleWithRunLoop (NSRunLoop.Current);
});
我认为,问题在于,这段代码可能运行在另外两层线程启动中。出于测试目的,我有以下代码,其中我需要上面的代码:
NSThread.Start(()=>{
int i = 0;
});
在中间线上有一个断点来确定它是否被击中。十次中有九次我会出现以下堆栈溢出:
Stack overflow in unmanaged: IP: 0x261ba35, fault addr: 0xb02174d0
Stack overflow in unmanaged: IP: 0x261ba35, fault addr: 0xb02174d0
(地址会发生变化,但经常重复)
十次中有一次代码完全按照预期工作,我在I=0时中断
为了进一步测试这一点,我将上述测试放在我的主AppDelegate.csFinishedLaunching
方法中。在那里,代码可靠地工作
为了进一步混淆问题,我将以下代码放在FinishedLaunching
的开头:
var fooThread = new Thread(() =>
{
var barThread = new Thread(()=>{
NSThread.Start(() =>
{
int i = 4;
});
});
barThread.Start();
});
fooThread.Start();
在fooThread.Start()上有断点代码>,barThread.Start()代码>和inti=4代码>代码完全按照预期工作,点按相反顺序命中
我的问题是,有没有人对如何开始对这件事进行辩护有什么想法?这太出乎意料了,我甚至不知道从哪里开始。一年后,我有一个答案给你: