为什么Runspace.OpenAsync()忽略InitialSessionState

本文关键字:忽略 InitialSessionState Runspace OpenAsync 为什么 | 更新日期: 2023-09-27 18:23:46

我正在编写与PowerShell接口的代码。我最初有以下内容:

using (var runspace = RunspaceFactory.CreateRunspace(initialSessionState))
{
    runspace.Open();

这个代码运行得很好。然而,由于这段代码实际上已经在异步方法中了,我写了以下内容只是为了进行实验:

public static Task OpenTaskAsync(this Runspace runspace)
{
    if (runspace.RunspaceStateInfo.State == RunspaceState.Opened)
        return Task.FromResult<object>(null);
    var tcs = new TaskCompletionSource<object>();
    EventHandler<RunspaceStateEventArgs> stateHandler = null;
    stateHandler = (o, e) =>
    {
        if (e.RunspaceStateInfo.Reason != null)
        {
            runspace.StateChanged -= stateHandler;
            tcs.TrySetException(e.RunspaceStateInfo.Reason);
        }
        else if (e.RunspaceStateInfo.State == RunspaceState.Opened)
        {
            runspace.StateChanged -= stateHandler;
            tcs.TrySetResult(null);
        }
    };
    runspace.StateChanged += stateHandler;
    runspace.OpenAsync();
    return tcs.Task;
}

然而,在将我的代码更改为以下代码后:

using (var runspace = RunspaceFactory.CreateRunspace(initialSessionState))
{
    await runspace.OpenTaskAsync();

我的测试现在失败了。原因是PowerShell无法再从导入到我的InitialSessionState(在创建运行空间之前)的模块中找到命令。我无法确定为什么会发生这种情况。我已经调试过,并且运行空间在该任务完成后是打开的并且可用的,在它完成之前,我不会继续调用任何命令。有什么想法吗?

为什么Runspace.OpenAsync()忽略InitialSessionState

我查看了reflector中的运行空间开放代码,发现了一件可以解释它的事情。在LocalRunspace.DoOpenHelper()中,StateChanged事件(当状态变为"Opened"时)在导入模块之前发生。作为一种变通方法,您似乎可以轮询正在设置的默认驱动器(在InitialSessionState.SetSessionStateDrive()中)。