Я пытаюсь создать второй цикл обработки сообщений для асинхронной обработки / фильтрации сообщений низкого уровня в C #.Он работает, создавая скрытую форму, выставляя ее свойство Handle для подключения, и запускает второй цикл сообщений в отдельном потоке.На данный момент я вполне доволен результатами, но не могу правильно выйти из второго цикла.Единственным обходным решением было установить для свойства IsBackground значение true, поэтому второй поток будет просто завершен (без обработки всех ожидающих сообщений) при выходе из основного приложения.
Вопрос заключается в следующем: как правильно завершить этот цикл сообщений, чтобывторой Application.Run () возвращает?Я пробовал разные подходы, создавая отдельный ApplicationContext и управляя различными событиями (Application.ApplicationExit, Application.ThreadExit, ApplicationContext.ThreadExit), но все они потерпели неудачу в условиях гонки, которые я не могу отладить.
Любая подсказка?Спасибо
Это код:
public class MessagePump
{
public delegate void HandleHelper(IntPtr handle);
public MessagePump(HandleHelper handleHelper, Filter filter)
{
Thread thread = new Thread(delegate()
{
ApplicationContext applicationContext = new ApplicationContext();
Form form = new Form();
handleHelper(form.Handle);
Application.AddMessageFilter(new MessageFilter(filter));
Application.Run(applicationContext);
});
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = true; // <-- The workaround
thread.Start();
}
}
public delegate bool Filter(ref Message m);
internal class MessageFilter : IMessageFilter
{
private Filter _Filter;
public MessageFilter(Filter filter)
{
_Filter = filter;
}
#region IMessageFilter Members
public bool PreFilterMessage(ref Message m)
{
return _Filter(ref m);
}
#endregion // IMessageFilter Members
}
Я использую его в главном конструкторе форм следующим образом:
_Completion = new ManualResetEvent(false);
MessagePump pump = new MessagePump(
delegate(IntPtr handle)
{
// Sample code, I did this form twain drivers low level wrapping
_Scanner = new TwainSM(handle);
_Scanner.LoadDs("EPSON Perfection V30/V300");
},
delegate(ref Message m)
{
// Asyncrhronous processing of the messages
// When the correct message is found -->
_Completion.Set();
}
РЕДАКТИРОВАТЬ :Полное решение в моем ответе.