ContextSwitchDeadlock on XNA (MonoGame) form built as class library

218 Views Asked by At

I'm using runtime dll initialization through Assembly.LoadFile to load additional viewports for my project. I've succesfully launched WPF form and CS-SDL form (both built as dll's) that way, but MonoGame form is giving me an error after 60 sec. of running:

Managed Debugging Assistant 'ContextSwitchDeadlock' has detected a problem. The CLR has been unable to transition from COM context 0x5b16f8 to COM context 0x5b1920 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. etc.

Plugin (form built as class library) init code:

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 method:

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();
    }

I'd like to know how to solve this (besides shutting off MDA). Should I implement message pumping explicitly?

Form is doing fine, it sees mouse/keyboard events and can be moved around. The only issue is the memory leak which can be related to this case (MDA description states it could cause memory leaks).

UPDATE: setting STA off for the XNA thread seems to supress this error, though I do not clearly understand why. Perhaps I should dive into the Windows inner mechanics deeper.

0

There are 0 best solutions below