Как завершить управляемый поток, заблокированный в неуправляемом коде?

У меня есть управляемый поток, который ожидает, заблокированный, в неуправляемом коде (а именно, это на вызове к NamedPipeServerStream. WaitForConnection (), какой ultimitely звонит в неуправляемый код и не предлагает тайм-ауту).

Я хочу завершить работу потока аккуратно.

Поток. Аварийное прекращение работы () не имеет никакого эффекта, пока код не возвращается к управляемой области, которую это не сделает, пока клиент не установит связь, которая мы не можем ждать).

Мне нужен путь, "потрясают" его из неуправляемого кода; или способ просто уничтожить поток даже, в то время как это находится на неуправляемой земле.

7
задан James Curran 23 April 2010 в 17:03
поделиться

3 ответа

Вы пробовали использовать неблокирующий NamedPipeServerStream.BeginWaitForConnection ?

using (NamedPipeServerStream stream = ...)
{
    var asyncResult = stream.BeginWaitForConnection(null, null);

    if (asyncResult.AsyncWaitHandle.WaitOne(5000))
    {
        stream.EndWaitForConnection(asyncResult);
        // success
    }
}

Вам не обязательно использовать фиксированный тайм-аут. Вы можете использовать ManualResetEvent , чтобы сигнализировать, когда поток должен прекратить ожидать соединения:

ManualResetEvent signal = new ManualResetEvent(false);

using (NamedPipeServerStream stream = ...)
{
    var asyncResult = stream.BeginWaitForConnection(_ => signal.Set(), null);

    signal.WaitOne();
    if (asyncResult.IsCompleted)
    {
        stream.EndWaitForConnection(asyncResult);
        // success
    }
}

// in other thread
void cancel_Click(object sender, EventArgs e)
{
    signal.Set();
}
19
ответ дан 6 December 2019 в 09:18
поделиться

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

  threads.ForEach(thread=> thread.Abort());
  threads.ForEach(thread=>
              {
                   var client = new PipeClient(ServiceName); 
                   client.Connect(); 
                   client.Dispose();
              });

При подключении он возвращается к управляемому коду, и срабатывает Abort () (поток перехватывает ThreadAbortException и очищает себя)

Это не работает в общем случае (то есть вопрос, заданный в title), но у меня это работает ...

0
ответ дан 6 December 2019 в 09:18
поделиться

Невозможно «аккуратно» завершить поток извне, если этот поток выполняет неуправляемый код. Есть несколько способов резко прервать поток, но, вероятно, это не то, что вам нужно.

Вместо этого следует использовать BeginWaitForConnection .

1
ответ дан 6 December 2019 в 09:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: