Почему мой код останавливается и не возвращает исключение? - PullRequest
8 голосов
/ 11 мая 2010

У меня есть некоторый код, который запускает несколько потоков, чтобы позволить им исполниться, затем использует цикл while, чтобы проверить текущее время, прошедшее с установленным периодом ожидания, или правильное количество обработанных результатов (проверяя int для объекта класса) (с Thread.Sleep() для ожидания между циклами)

Как только цикл while настроен на выход, он вызывает Abort() в потоках и должен возвращать данные в функцию, которая вызывает метод.

При отладке и пошаговом выполнении кода я обнаружил, что в коде, выполняемом в отдельных потоках, могут быть исключения, и в некоторых случаях я обращаюсь с ними соответствующим образом, а в других случаях я не хочу делать что-то конкретное.

Что я видел, так это то, что мой код входит в цикл while, и поток спит, и из моей функции ничего не возвращается, ни данные, ни исключение. Выполнение кода просто полностью прекращается.

Есть идеи, что может произойти?


Пример кода:

System.Threading.Thread sendThread = 
     new System.Threading.Thread(new System.Threading.ThreadStart(Send));
sendThread.Start();

System.Threading.Thread receiveThread = 
     new System.Threading.Thread(new System.Threading.ThreadStart(Receive));
receiveThread.Start();

// timeout
Int32 maxSecondsToProcess = this.searchTotalCount * timeout;
DateTime timeoutTime = DateTime.Now.AddSeconds(maxSecondsToProcess);
Log("Submit() Timeout time: " + timeoutTime.ToString("yyyyMMdd HHmmss"));

// while we're still waiting to receive results & haven't hit the timeout, 
// keep the threads going
while (resultInfos.Count < this.searchTotalCount && DateTime.Now < timeoutTime)
{
    Log("Submit() Waiting...");
    System.Threading.Thread.Sleep(10 * 1000); // 1 minute
}

Log("Submit() Aborting threads");    // <== this log doesn't show up

sendThread.Abort();
receiveThread.Abort();

return new List<ResultInfo>(this.resultInfos.Values);

Ответы [ 2 ]

5 голосов
/ 11 мая 2010

Итак, вам действительно не следует использовать метод Sleep в потоке для целей синхронизации. Для этого и предназначены классы синхронизации, такие как ManualResetEvent , а также модель асинхронного программирования ( IAsyncResult реализации).

Лучшим подходом здесь было бы создание делегата с подписью метода, который вы хотите запустить асинхронно. Затем назначьте группу методов, которая является точкой входа для асинхронной операции, экземпляру этого делегата и вызовите BeginInvoke для экземпляра делегата.

Оттуда вы будете запускать цикл, ожидая, что вы вызовете перегрузку WaitOne для WaitHandle , возвращаемого свойством AsyncWaitHandle реализации IAsyncResult возвращается при вызове BeginInvoke на делегата.

Это приведет к меньшей зависимости от метода Sleep (что в целом плохо для синхронизации).

Если у вас есть возможность использовать .NET 4.0, вы можете взглянуть на Класс задач в пространстве имен System.Threading.Tasks , поскольку он обеспечивает еще лучший способ обработки асинхронной обработки, отмены и ожидания.

3 голосов
/ 11 мая 2010

Thread.Abort Вызывает исключение ThreadAbortException в потоке, для которого оно вызывается

Вы не должны позволять исключениям выходить из ваших потоков никогда - у вас должна быть обработка исключений в вашем поточном объекте. По крайней мере, должен быть блок try \ catch вокруг кода в поточном объекте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...