我有一个相当复杂的Xamarin.Mac应用程序。事实上,它是一个Windows窗体应用程序,但我们使用Mono for Mac与本机Mac GUI兼容。我们的业务逻辑组件之一涉及使用FSWatcher监视文件系统的更改。不幸的是,Mac上的FSWatcher严重受损,让我们通过Xamarin.Mac使用本机FSEvents API。
在业务逻辑的深处,我有一个名为CBFileSystemWatcher的自定义类,它包装.NET FSWatcher,并且在mac上提供了FSWatcher期望的业务逻辑和mac上的FSEvents之间的适配器。在这个兼容性类中,我有
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;
});
在中间线上有一个断点,以确定它是否被击中。 10次中有9次我得到以下堆栈溢出:
Stack overflow in unmanaged: IP: 0x261ba35, fault addr: 0xb02174d0
Stack overflow in unmanaged: IP: 0x261ba35, fault addr: 0xb02174d0
(地址发生变化,但经常重复) 十分之一的代码与预期完全一致,我在i = 0
上休息为了进一步测试,我将上述测试放在我的主AppDelegate.cs FinishedLaunching
方法中。在那里,代码可靠地工作。
为了进一步混淆问题,我在FinishedLaunching
:
var fooThread = new Thread(() =>
{
var barThread = new Thread(()=>{
NSThread.Start(() =>
{
int i = 4;
});
});
barThread.Start();
});
fooThread.Start();
对于fooThread.Start();
,barThread.Start();
和int i = 4;
上的断点,代码的工作方式完全符合预期,其中的点按相反顺序命中。
我的问题是,有没有人对如何开始取消这个有任何想法? SO是如此突然,我甚至不知道从哪里开始。
答案 0 :(得分:1)