是否将其中一个嵌入另一个中?在过去,我有一个挂起/死锁问题,我可以在执行顶部代码块时重现,当我将其更改为底部代码块时,我无法重现...我真的不明白它在时间,我还是没有。是否有关于Lock& amp;我应该知道的InvokeOnMainThread?我可以提供有关我正在做的事情的更多细节,但这更像是一个普遍问题而不是任何事情......
假设我想在后台线程中使用“DoStuff”。我有一个从多个线程访问的变量。
lock( stuff )
{
InvokeOnMainThread ( delegate {
stuff.DoStuff();
});
}
替代
InvokeOnMainThread ( delegate {
lock( stuff )
{
stuff.DoStuff();
}
});
添加信息:我的iOS应用程序具有在后台线程中运行的连接管理器功能。连接管理器功能负责保持活动和管理异步网络套接字连接。有很多实例我需要在执行操作时需要InvokeOnMainThread,否则我将收到以下错误“UIKit一致性错误:您正在调用只能从UI线程调用的UIKit方法。”
答案 0 :(得分:1)
两者之间的区别在于第二个代码块在DoStuff之前不会阻止在执行线程上执行任何操作。
示例:
lock (stuff) {
InvokeOnMainThread ( delegate { Console.WriteLine ("a"); } }
}
Console.WriteLine ("b");
将打印:
a
b
这段代码:
InvokeOnMainThread ( delegate {
lock (stuff) {
Console.WriteLine ("a");
}
}
Console.WriteLine ("b");
通常(但不一定)打印:
b
a
现在这并不能解释为什么第二个区块会修复比赛条件,但是我的猜测是它只会改变比赛条件,你不会再次击中它(所以不要修复它,只是隐藏它)。
答案 1 :(得分:0)
因此,如果我们假设这只是你使用锁(东西)的方法,那么只有逻辑解释为什么第一种情况会导致你死锁的是线程A(背景thead)来到这个方法并进入内部锁(东西)。所以现在东西被锁定在线程A上。现在线程A调用MainThread,如果你从stuff.DoStuff()调用这个方法,你将会遇到死锁,因为MainThread会遇到锁(东西),它会等到线程A释放锁(东西)但是,当MainThread完成调用时,线程A将释放...导致死锁。
即使你没有从stuff.DoStuff()调用这个方法,也有可能在第一种情况下从MainThread死锁发生的任何地方调用此方法只是区别是InvokeOnMainThread没有执行stuff.DoStuff()但它只排队到在MainThread上执行导致同样的死锁情况。
现在有了第二个例子,其中lock(stuff)在InvokeOnMainThread中,因此没有机会发生死锁,因为lock(stuff)只在MainThread上执行它,所以它没有任何功能,所以你可以删除它。因为在MainThread上执行代码已经100%同步“锁定”了。