Я разрабатываю программу, которая использует алгоритм Bonjour для поиска сервисов в сети. Я загрузил Bonjour SDK для Windows. На .Net было два примера приложений. Оба являются проектом Windows Forms. Образцы работают нормально, но когда я попытался реализовать образец консольного приложения, я получил AccessViolationException. Вот мой код:
class Program
{
static void Main(string[] args)
{
DNSSDService service = new DNSSDService();
DNSSDEventManager eventManager = new DNSSDEventManager();
eventManager.ServiceFound += new _IDNSSDEvents_ServiceFoundEventHandler(eventManager_ServiceFound);
//next line raises AccessViolationException
DNSSDService browse = service.Browse(0, 0, "_psia._tcp", null, eventManager);
Console.ReadKey();
}
static void eventManager_ServiceFound(DNSSDService browser, DNSSDFlags flags, uint ifIndex, string serviceName, string regtype, string domain)
{
//TODO: some logic
}
}
Я нашел решение - все методы из библиотеки Bonjour должны вызываться из потока STA. Поэтому я добавил атрибут [STAThread] в метод Main. Теперь код выглядит так:
class Program
{
[STAThread]
static void Main(string[] args)
{
DNSSDService service = new DNSSDService();
DNSSDEventManager eventManager = new DNSSDEventManager();
eventManager.ServiceFound += new _IDNSSDEvents_ServiceFoundEventHandler(eventManager_ServiceFound);
DNSSDService browse = service.Browse(0, 0, "_psia._tcp", null, eventManager);
Console.ReadKey();
}
static void eventManager_ServiceFound(DNSSDService browser, DNSSDFlags flags, uint ifIndex, string serviceName, string regtype, string domain)
{
//TODO: some logic
}
}
Я решил проблему с AccessViolationException, но получил новое. После вызова метода Browse должно вызываться событие ServiceFound для каждой службы, определенной в сети. Но этого не произошло. После некоторого времени исследования я обнаружил, что мне нужно запустить насос сообщений, чтобы получать все эти события. Итак, окончательный код выглядит так:
class Program
{
[STAThread]
static void Main(string[] args)
{
DNSSDService service = new DNSSDService();
DNSSDEventManager eventManager = new DNSSDEventManager();
eventManager.ServiceFound += new _IDNSSDEvents_ServiceFoundEventHandler(eventManager_ServiceFound);
DNSSDService browse = service.Browse(0, 0, "_psia._tcp", null, eventManager);
Application.Run();
}
static void eventManager_ServiceFound(DNSSDService browser, DNSSDFlags flags, uint ifIndex, string serviceName, string regtype, string domain)
{
//TODO: some logic
}
}
Чтобы остановить цикл сообщений, вызовите Application.Exit ().
eventManager_ServiceFound
? - person Yoda   schedule 11.01.2014