1
我正在编写与PowerShell接口的代码。我原本有以下几种:为什么Runspace.OpenAsync()会忽略InitialSessionState?
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的模块中找到命令(在运行空间创建之前)。我无法确定这是为什么。我已经调试过,并且在此任务完成后,运行空间已打开并可用,并且在它执行之前,我不会继续调用任何命令。有任何想法吗?
有趣的是,我也看了反编译的代码(通过ReSharper/dotPeek)。我一定错过了那个细节。我再次检查,你是正确的。这是不幸的,因为似乎没有一个干净的替代解决方案(即你提到的投票)。好吧。我想知道他们为什么会提供异步方法而无法等待它们(即使是IAsyncResult)。 –
我只能推测,但从某种意义上说,在这个点上运行空间是“打开”的。这是“为商业做好准备”。不幸的是,尚未准备好需要导入模块的业务。你可以改变初始会话状态来执行一些PowerShell代码(也许是一个小模块)来表明它已被加载。 (现在你可以玩“挑选最少的攻击手段”) –