我正在通过Assembly.LoadFile使用运行时dll初始化来为我的项目加载其他视口。我已经成功地推出了WPF表单和CS-SDL表单(都是作为dll构建的),但是MonoGame表单在60秒后给我一个错误。跑步:
托管调试助手'ContextSwitchDeadlock'检测到了 问题。 CLR无法从COM上下文转换 0x5b16f8到COM上下文0x5b1920持续60秒。拥有的线程 目的地上下文/公寓最有可能做非 抽空等待或处理很长时间的运行操作 抽取Windows消息。等
插件(构建为类库的表单)init代码:
foreach (PluginInfo plginfo in _gameManager.XmlReader.ReadViewPlugins(System.Environment.CurrentDirectory + "\\plugins\\plugins.xml"))
{
if (plginfo.Correct)
{
//create new thread for every plugin
Thread thread = new Thread(RunViewControlPlugin);
thread.Name = plginfo.Name;
//set it to single-threaded if plugin requires so
if (plginfo.STA)
thread.SetApartmentState(ApartmentState.STA);
thread.Start(plginfo);
}
}
RunViewControl方法:
void RunViewControlPlugin(object data)
{
PluginInfo plginfo = (PluginInfo)data;
string path = System.Environment.CurrentDirectory + "\\plugins\\" + plginfo.FileName;
//load assembly from the path and create instance of the required type
Assembly assembly = Assembly.LoadFile(path);
Type type = assembly.GetType(plginfo.AssemblyData);
IViewControlPlugin plugin = (IViewControlPlugin)Activator.CreateInstance(type);
lock(locker)
{
_viewcontrolpluginList.Add(plugin);
}
//on shutdown close dispatcher, remove plugin from the active plugins list and unsubscribe
EventHandler handler = null;
handler = (s, e) => {
if (plginfo.DispatcherNeeded)
System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvokeShutdown(System.Windows.Threading.DispatcherPriority.Background);
_gameManager.DebugLogger.LogGeneralInfo(plginfo.Name+" stopped.");
_viewcontrolpluginList.Remove(plugin);
plugin.Closed -= handler;
};
plugin.Closed += handler;
//send manager instances to the plugin
plugin.AddGameDataManager(_gameDataManager);
plugin.AddGameManager(_gameManager);
_gameManager.DebugLogger.LogGeneralInfo(plginfo.Name + " started.");
//start dispatcher (wpf forms require dispatcher to run)
if (plginfo.DispatcherNeeded)
System.Windows.Threading.Dispatcher.Run();
plugin.Start();
}
我想知道如何解决这个问题(除了关闭MDA)。我应该明确地实施消息抽取吗?
表单正常,它可以看到鼠标/键盘事件并且可以移动。唯一的问题是内存泄漏,这可能与这种情况有关(MDA描述说它可能导致内存泄漏)。
UPDATE :为XNA线程设置STA关闭似乎压制了这个错误,虽然我不清楚为什么。也许我应该深入研究Windows内部机制。