I receive the following error after running my WPF application for the fourth consecutive time:
Fail to create a runspace because you have exceeded the maximum number of connections allowed : 3 for the policy party : MaxConcurrency. Please close existing runspace and try again.
This error does not occur when opening the Runspace
and PowerShell
objects through a using (Runspace rs = RunspaceFactory.CreateInstance())...
statement, as the resources seem to be properly disposed.
However, the way that this app is structured I would like to keep the Runspace/PowerShell object open between transactions because it takes a long time to create a remote session with Office 365 and I cannot keep users waiting to re-establish a remote session between every transaction.
When I keep these objects alive I then have to dispose of them manually as they are not contained within a using
statement. I am using the following code:
namespace O365Wrapper
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
public App()
{
InitializeComponent();
}
[STAThread]
public static void Main()
{
App app = new App();
cOofSettingsView view = new cOofSettingsView();
app.Run(view);
Thread.GetDomain().UnhandledException += new UnhandledExceptionEventHandler(OnUnhandledException);
AppDomain.CurrentDomain.ProcessExit += new EventHandler(OnProcessExit);
}
public static void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
var ex = (Exception) e.ExceptionObject;
MessageBox.Show(ex.Message);
Environment.Exit(System.Runtime.InteropServices.Marshal.GetHRForException(ex));
}
public static void OnProcessExit(object sender, EventArgs e)
{
cPSConnection.DisposePowerShellEnvironment();
}
}
}
And in cPSConnection
:
private static void InitializePowerShellEnvironment()
{
if (_psrunspace == null || _psshell == null)
{
_psrunspace = RunspaceFactory.CreateRunspace();
_psrunspace.Open();
_psshell = PowerShell.Create();
_psshell.Runspace = _psrunspace;
CreatePowerShellSession();
}
}
public static void DisposePowerShellEnvironment()
{
if (_psshell != null)
{
_psshell.Dispose();
}
if (_psrunspace != null)
{
_psrunspace.Dispose();
}
_psshell = null;
_psrunspace = null;
}
According to msdn the Runspace.Dispose
method calls Runspace.Close
if it has not been closed already.
One last item to note: _psshell
and _psrunspace
are only instantiated one time there are no incidental duplicate items created that might be lingering - the cPSConnection
class is using the Singleton pattern.
The code that I currently have in place is an accumulation of borrowed code from already researching this problem, and I am still having no luck. Not sure where else to look. Any help would be much appreciated. Thanks!