Почему мой вызов Runspace.Open () не возвращается? - PullRequest
2 голосов
/ 22 сентября 2010

Я пытаюсь интегрировать новый код, который я написал для программного взаимодействия с 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    

1 Ответ

2 голосов
/ 22 сентября 2010

Возможно ли, что при запуске программы в пуле потоков этот поток блокируется?Возможно, вы действительно хотите позвонить OpenAsync , а не Open.

...