Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Don';我不知道为什么C#PowerShell运行空间不规则关闭_C#_Asp.net Mvc 3_Powershell_Office365 - Fatal编程技术网

Don';我不知道为什么C#PowerShell运行空间不规则关闭

Don';我不知道为什么C#PowerShell运行空间不规则关闭,c#,asp.net-mvc-3,powershell,office365,C#,Asp.net Mvc 3,Powershell,Office365,我有一个MVC web应用程序,它显示了我们广告中用户的一些信息。广告与Office 365同步,因此使用UPN,我可以使用从Office 365检索许可证信息。基本上这一切都很好 由于初始化cmdletConnect-MsolService需要一些时间才能完成,因此我对我的Office365Connector类使用了某种单例模式。在我的Global.asax中的Application\u Start()中初始化单例实例,在Application\u End()中处置它。连接器类只使用了我的Po

我有一个MVC web应用程序,它显示了我们广告中用户的一些信息。广告与Office 365同步,因此使用UPN,我可以使用从Office 365检索许可证信息。基本上这一切都很好

由于初始化cmdlet
Connect-MsolService
需要一些时间才能完成,因此我对我的
Office365Connector
类使用了某种单例模式。在我的
Global.asax
中的
Application\u Start()
中初始化单例实例,在
Application\u End()中处置它。连接器类只使用了我的
PowerShellInvoker
类的一个实例,顾名思义,它封装了PowerShell调用。
PowerShellInvoker
构造函数中的PowerShell初始化代码如下所示:

公共PowerShellInvoker(参数字符串[]模块)
{
var iss=InitialSessionState.CreateDefault();
iss.导入模块(模块);
iss.ThrowOnRunspaceOpenError=true;
_runspace=RunspaceFactory.CreateRunspace(iss);
_Open();
_invoker=newrunspaceinvoke(_runspace);
}
Office365Connector
类调用此构造函数,并将
“MSOnline”
作为参数。
MSOnline
模块包含Office 365的cmdlet。我保留
\u运行空间
\u调用程序
字段,以便以后执行命令。这两个字段都将在
PowerShellInvoker
Dispose
方法中处理(在处理
Office365Connector
类时调用)。脚本执行由以下代码行完成:

\u invoker.Invoke(脚本文本);
介绍到此为止——现在真正的问题来了:

在我的应用程序中,我有一个用户列表。当我单击一个用户时,使用AJAX请求加载附加信息。在这个请求中,我的应用程序使用
Office365Connector
类的单例实例来检索用户的许可证信息。在大多数情况下,这一切都非常有效。但有时AJAX请求的结果是代码500。在调试我的源代码时,我偶然发现在上面的“Invoke”行的
PowerShellInvoker
中抛出了一个异常,告诉我运行空间不再打开,我不知道为什么。我甚至不能真正复制它。有时,当我单击第二个用户时会发生错误。有时,错误发生在第10个或第15个用户。我已经考虑过MVC使用的一些奇怪的清理、超时或垃圾收集技术,但我还没有得出结论。嗯,运行空间关闭不能是基于时间的,因为“用户点击”之间的时间只有几秒钟

Connect-MsolService
cmdlet创建到Office 365的连接,但不返回任何内容。因此,如果需要,重新创建运行空间不是一个解决办法,因为这将由
PowerShellInvoker
类完成,而
Office365Connector
不会知道它必须重新连接到Office 365。(这也不能解决问题。)组合这两个类也不是解决方案,因为在其他地方也使用了
PowerShellInvoker

那么,有谁能告诉我如何防止运行空间关闭,或者为什么关闭

编辑:更多代码

可以找到完整的
PowerShellInvoker

在Office365Connector类中,当前有很多开销。以下是一些片段:

构造函数中的初始化:

var cred = new PSCredential(adminUpn, adminPassword);

_psi = new PowerShellInvoker("MSOnline");
_psi.ExecuteCommand("Connect-MsolService", new { Credential = cred });
public IEnumerable<string> GetUserLicenses(string upn)
{
    PSObject[] licenses = _psi.ExecuteScript(string.Format("(Get-MsolUser -UserPrincipalName \"{0}\").Licenses | % {{ $_.AccountSkuId }}", upn)).ToArray();

    // no licenses: a list with one element (which is null) is returned.
    if (licenses.Length == 1 && licenses[0] == null)
    {
        licenses = new PSObject[0];
    }

    return licenses.Select(pso => pso.ToString()).ToList();
}
检索UPN许可证的方法:

var cred = new PSCredential(adminUpn, adminPassword);

_psi = new PowerShellInvoker("MSOnline");
_psi.ExecuteCommand("Connect-MsolService", new { Credential = cred });
public IEnumerable<string> GetUserLicenses(string upn)
{
    PSObject[] licenses = _psi.ExecuteScript(string.Format("(Get-MsolUser -UserPrincipalName \"{0}\").Licenses | % {{ $_.AccountSkuId }}", upn)).ToArray();

    // no licenses: a list with one element (which is null) is returned.
    if (licenses.Length == 1 && licenses[0] == null)
    {
        licenses = new PSObject[0];
    }

    return licenses.Select(pso => pso.ToString()).ToList();
}
public IEnumerable GetUserLicenses(字符串upn)
{
PSObject[]licenses=_psi.ExecuteScript(string.Format(“(Get-MsolUser-UserPrincipalName\“{0}\”)。licenses |%{{{$\u.AccountSkuId}}}”,upn)).ToArray();
//无许可证:返回一个包含一个元素(为null)的列表。
if(licenses.Length==1&&licenses[0]==null)
{
许可证=新的PSObject[0];
}
返回许可证。选择(pso=>pso.ToString()).ToList();
}

如您所见,我在方法返回值中添加了一些
ToList
s(特别是在
PowerShellInvoker
中)。我这样做是因为我想防止延迟执行枚举,因为我认为这可能是关闭运行空间的原因。

好吧,这是我自己犯的一个愚蠢的错误-尽管我真的不明白MVC为什么这样做:

在解决该问题的多次尝试中,我将我的
office365连接器的处置代码
移动到应用程序的
Dispose
方法中(在
Global.asax.cs
)。在那之后,我显然修复了最初的错误,但由于处理的问题,它没有成功。显然,处理应用程序实例的频率高于“结束”。当我将代码移回它所属的
Application\u End()


这使得我原来的问题有点无效,因为我写到我的dispose代码已经在
应用程序中\u End()
:-\

我没有答案,但我有兴趣尝试找出答案。您是否可以共享更多代码?另外,您是否尝试过在打开运行空间后立即启动PowerShell成绩单?看看它是否记录了一些有用的东西会很有趣。@ElijahW.Gagne我编辑了这个问题并添加了更多的代码。我会尽快尝试成绩单的想法。谢谢你的提问和回答,伙计-帮助我为PS提供商写测试!