为什么Runspace.OpenAsync()会忽略InitialSessionState?

时间:2013-07-17 23:53:40

标签: c# powershell async-await

我正在编写与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的模块中找到命令(在创建运行空间之前)。我无法确定为什么会这样。我已经调试并且运行空间在此任务完成后打开并可用,并且我不会继续调用任何命令,直到它完成。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

我查看了反射器中的运行空间开放代码,并看到一个可能解释它的东西。在LocalRunspace.DoOpenHelper() {/ 1}}事件(当状态更改为“已打开”时)在导入模块之前发生。看起来您可以在正在设置的默认驱动器上进行轮询(在StateChanged中)作为解决方法。