Как избавиться от объектов Runspace и PowerShell из проекта WPF с помощью C # - PullRequest
0 голосов
/ 27 сентября 2018

Я получаю следующую ошибку после запуска моего приложения WPF четвертый раз подряд:

Не удалось создать пространство выполнения, поскольку превышено максимально допустимое количество подключений: 3 для стороны политики:MaxConcurrency.Закройте существующее пространство выполнения и повторите попытку.

Эта ошибка не возникает при открытии объектов Runspace и PowerShell с помощью оператора using (Runspace rs = RunspaceFactory.CreateInstance())..., так как ресурсы, по-видимому, расположены правильно.

Однако, как структурировано это приложение, я бы хотел, чтобы объект Runspace / PowerShell оставался открытым между транзакциями, поскольку создание удаленного сеанса с Office 365 занимает много времени, и я не могу заставить пользователей ждать-установить удаленный сеанс между каждой транзакцией.

Когда я сохраняю эти объекты живыми, мне приходится их утилизировать вручную, поскольку они не содержатся в операторе using.Я использую следующий код:

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

И в 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;
}

Согласно msdn вызов метода Runspace.Dispose Runspace.Close, еслион еще не был закрыт.

И еще один последний замечание: _psshell и _psrunspace создаются только один раз, когда не создано ни одного случайного дублирующегося элемента, который мог бы остаться - класс cPSConnection используетшаблон синглтона.

Код, который у меня есть на данный момент, представляет собой скопление заимствованного кода из уже изученного вопроса, и мне все еще не повезло.Не уверен, где еще искать.Любая помощь приветствуется.Спасибо!

...