Я пытаюсь интегрировать новый код, который я написал для программного взаимодействия с Exchange 2010 через Remote Powershell, в существующее приложение WinForms. Мой код работает в изолированном тестовом приложении, но когда я запускаю код в контексте моего приложения, вызов Runspace.Open()
блоков в течение очень долгого времени - намного превышает значение OpenTimeout
60 секунд, которое я указываю в WSManConnectionInfo
экземпляр. Для меня это говорит о том, что в коде нашего приложения есть что-то, что создает проблему, но у меня возникают проблемы с определением возможных причин. Приложение является многопоточным и использует BackgroundThreadWorker
и ThreadPool
; фактически мой код запускается через ThreadPool
в приложении. Но я уже пытался смоделировать это в своем тестовом жгуте, и код прекрасно работает, когда вызывается как обратный вызов из ThreadPool
.
Вот код (с удаленной обработкой ошибок и рядом расположенными определениями констант):
const string EXCHANGE_PS_URI_FORMAT = "http://{0}/PowerShell/";
string uriString = string.Format(EXCHANGE_PS_URI_FORMAT, HostName);
Uri connectionUri = new Uri(uriString);
PSCredential creds = new PSCredential(username, securePwd);
const string EXCHANGE_PS_SCHEMA_URL =
"http://schemas.microsoft.com/powershell/Microsoft.Exchange";
WSManConnectionInfo connectionInfo =
new WSManConnectionInfo(connectionUri, EXCHANGE_PS_SCHEMA_URL, creds);
const int DEFAULT_OPEN_TIMEOUT = 1 * 60 * 1000; // 1 minute
connectionInfo.OpenTimeout = DEFAULT_OPEN_TIMEOUT;
const int DEFAULT_OPERATION_TIMEOUT = 4 * 60 * 1000; // 4 minutes
connectionInfo.OperationTimeout = DEFAULT_OPERATION_TIMEOUT;
using (Runspace rs = RunspaceFactory.CreateRunspace(connectionInfo))
{
// BUGBUG: WHY IS THIS FAILING TO RETURN?
rs.Open(); // <-- HANGS HERE
ICollection<PSObject> newReqResults = null;
PipelineReader<object> newReqErrors = null;
try
{
using (Pipeline pipeline = rs.CreatePipeline())
{
// cmd instance is already instantiated with cmdlet info, params, etc.
pipeline.Commands.Add(cmd);
//Invoke the command and return the results and errors
newReqResults = pipeline.Invoke();
newReqErrors = pipeline.Error;
}
}
// Code to parse results and/or errors...
Стек вызовов, когда код висит на Runspace.Open()
, кажется, показывает, что внутренний код .NET застрял при ожидании вызова, но я не знаю, как поступить. Как я уже говорил ранее, этот код прекрасно работает в моем тестовом приложении, даже если он вызывается как обратный вызов ThreadPool, поэтому мне интересно, что может быть в нашем основном коде приложения, которое может вызывать это (контекст синхронизации или идентификатор потока или что-то еще? ) Любая помощь будет принята с благодарностью. Пожалуйста, дайте мне знать, если я не включил какую-либо соответствующую информацию, и я рад включить ее. Спасибо!
[In a sleep, wait, or join]
mscorlib.dll!System.Threading.WaitHandle.WaitOne(long timeout, bool exitContext) + 0x2f bytes
mscorlib.dll!System.Threading.WaitHandle.WaitOne(int millisecondsTimeout, bool exitContext) + 0x25 bytes
mscorlib.dll!System.Threading.WaitHandle.WaitOne() + 0xd bytes
System.Management.Automation.dll!System.Management.Automation.Runspaces.AsyncResult.EndInvoke() + 0x14 bytes
System.Management.Automation.dll!System.Management.Automation.Runspaces.Internal.RunspacePoolInternal.EndOpen(System.IAsyncResult asyncResult) + 0xb2 bytes
System.Management.Automation.dll!System.Management.Automation.Runspaces.Internal.RemoteRunspacePoolInternal.Open() + 0x1a bytes
System.Management.Automation.dll!System.Management.Automation.Runspaces.RunspacePool.Open() + 0x48 bytes
System.Management.Automation.dll!System.Management.Automation.RemoteRunspace.Open() + 0x73 bytes