ContextSwitchDeadlock в форме XNA (MonoGame), созданной как библиотека классов
Я использую инициализацию dll инициализации через Assembly.LoadFile, чтобы загрузить дополнительные видовые окна для моего проекта. Таким образом, я успешно запустил WPF-форму и CS-SDL-форму (обе созданы как dll), но форма MonoGame выдает ошибку через 60 секунд. бега:
Помощник по управляемой отладке ContextSwitchDeadlock обнаружил проблему. CLR не удалось перейти из контекста COM 0x5b16f8 в контекст COM 0x5b1920 в течение 60 секунд. Поток, который владеет целевым контекстом / квартирой, скорее всего либо выполняет некачивающее ожидание, либо обрабатывает очень длительную операцию без прокачки сообщений Windows. и т.п.
Плагин (форма построена как библиотека классов) код инициализации:
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 говорится, что это может вызвать утечку памяти).
ОБНОВЛЕНИЕ: отключение STA для потока XNA, похоже, подавляет эту ошибку, хотя я не совсем понимаю, почему. Возможно, мне следует глубже погрузиться во внутреннюю механику Windows.