gpt4 book ai didi

c# - 使用 Powershell RunspacePool 多线程从 C# 到远程服务器

转载 作者:行者123 更新时间:2023-11-30 18:32:38 25 4
gpt4 key购买 nike

我正在尝试使用 Powershell RunspacePool 为远程服务器创建一些 C# 代码。将 maxRunspaces 设置为 1 时一切正常,但将其设置为 2 时会出现问题。

var connectionInfo = new WSManConnectionInfo(target, shellUri, credential);

using (RunspacePool pool = RunspaceFactory.CreateRunspacePool(1, 2,
connectionInfo))
{
pool.ApartmentState = System.Threading.ApartmentState.STA;
pool.ThreadOptions = PSThreadOptions.UseNewThread;
pool.Open();
var tasks = new List<Task>();

for (var i = 0; i < 12; i++)
{
var taskID = i;
var ps = PowerShell.Create();
ps.RunspacePool = pool;
ps.AddCommand("Get-NAVServerInstance");
var task = Task<PSDataCollection<PSObject>>.Factory.FromAsync(
ps.BeginInvoke(), r => ps.EndInvoke(r));
System.Diagnostics.Debug.WriteLine(
string.Format("Task {0} created", task.Id));
task.ContinueWith(t => System.Diagnostics.Debug.WriteLine(
string.Format("Task {0} completed", t.Id)),
TaskContinuationOptions.OnlyOnRanToCompletion);
task.ContinueWith(t => System.Diagnostics.Debug.WriteLine(
string.Format("Task {0} faulted ({1} {2})", t.Id,
t.Exception.InnerExceptions.Count,
t.Exception.InnerException.Message)),
TaskContinuationOptions.OnlyOnFaulted);
tasks.Add(task);
}

Task.WaitAll(tasks.ToArray());
}

在服务器上,我已经使用 shellUri 指向的 Register-PSSessionConfiguration 注册了一个 session 配置。该配置使用加载管理单元 (Add-PSSnapin 'MySnapin') 的启动脚本。如前所述,这在使用最多 1 个运行空间时效果很好。但是最多有 2 个运行空间,第一个任务完成,下一个任务给出错误“运行启动脚本引发错误:已添加具有相同键的项目。”另一个任务由于连接损坏而失败。加载 span 2 次似乎有问题。所以我将启动脚本更改为

if ((Get-PSSnapin -Name 'MySnapin' -ErrorAction SilentlyContinue) -eq $null)
{
Add-PSSnapin 'MySnapin'
}

在那种情况下,打开池已经失败并出现错误:运行启动脚本引发错误:找不到与模式“MySnapin”匹配的 Windows PowerShell 管理单元。检查模式,然后重试该命令。评论 Add-PSSnapin 行,仍然会引发错误,因此是 Get-PSSnapin 命令引发该错误。所以看起来 ErrorAction SilentlyContinue 没有受到尊重。

有什么想法吗?

第二个问题:pool.ApartmentState 和 pool.ThreadOptions 的推荐设置是什么?找不到关于它的必要文档。

更新:

我尝试了 ApartmentState 和 ThreadOptions 的所有组合,但没有任何区别(除了 STA 和 UseCurrentThread 的组合不起作用,因为服务器进程运行在 MTA 模式下,这是正常的)。

很明显这是 PSSnapin cmdlet 的问题。在正常的 Powershell 进程中,多次调用 Add-PSSnapin 没有问题,并且 Get-PSSnapin cmdlet 遵守 ErrorAction SilentlyContinue。这两件事似乎都不适用于启动脚本。很奇怪。

但现在我没有使用 Add-PSSnapin,而是尝试使用 Import-Module 来加载程序集并且效果很好。

我现在不明白的是,改变 maxRunspaces 参数(1、2 或 3)似乎不会对总持续时间产生任何影响。但这可能是因为与网络流量和延迟相比,服务器上的操作相对较小。我应该尝试一个漫长的过程。

更新 2:

好的,我现在已经用一个简单的 Start-Sleep 命令进行了测试,我可以清楚地看到多线程工作正常。

所以最终的问题仍然存在于上面的粗斜体文本中。虽然我可以通过使用 Import-Module 来解决它

最佳答案

首先:-ErrorAction SilentlyContinue 仅适用于“非终止”错误。终止错误是抛出的,而不是写入的,必须被捕获,而不是被抑制。 请不要让我开始。

换句话说,将其包装在 try { ... } catch { ... } block 中,而不是使用 ErrorAction 标志。

第二:你为什么要尝试将它加载为管理单元? Snapins 基本上已弃用。 MSDN 文档上的措辞是“请注意,Windows PowerShell 2.0 引入了对模块的支持,这是添加 cmdlet 和提供程序的首选方法。”

它们是一个死功能,不会被扩展,此时完全被模块取代。你说它适用于 Import-Module。这就是你的答案。导入模块。不要使用旧方法。

关于c# - 使用 Powershell RunspacePool 多线程从 C# 到远程服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18382401/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com