У меня есть управляемый поток, который ожидает, заблокированный, в неуправляемом коде (а именно, это на вызове к NamedPipeServerStream. WaitForConnection (), какой ultimitely звонит в неуправляемый код и не предлагает тайм-ауту).
Я хочу завершить работу потока аккуратно.
Поток. Аварийное прекращение работы () не имеет никакого эффекта, пока код не возвращается к управляемой области, которую это не сделает, пока клиент не установит связь, которая мы не можем ждать).
Мне нужен путь, "потрясают" его из неуправляемого кода; или способ просто уничтожить поток даже, в то время как это находится на неуправляемой земле.
Вы пробовали использовать неблокирующий 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();
}
Фактически, решение, которое я использовал (которое пришло мне в голову, когда я писал вопрос), заключалось в том, чтобы после прерывания всех потоков просто создать (и немедленно удалить) клиента для каждого потока.
threads.ForEach(thread=> thread.Abort());
threads.ForEach(thread=>
{
var client = new PipeClient(ServiceName);
client.Connect();
client.Dispose();
});
При подключении он возвращается к управляемому коду, и срабатывает Abort () (поток перехватывает ThreadAbortException и очищает себя)
Это не работает в общем случае (то есть вопрос, заданный в title), но у меня это работает ...
Невозможно «аккуратно» завершить поток извне, если этот поток выполняет неуправляемый код. Есть несколько способов резко прервать поток, но, вероятно, это не то, что вам нужно.
Вместо этого следует использовать BeginWaitForConnection
.