我正在开发一个使用 Bonjour 算法在网络中查找服务的程序。我下载了适用于 Windows 的 Bonjour SDK。.Net 上有两个示例应用程序。两者都是 Windows 窗体项目。示例工作正常,但是当我尝试实现示例控制台应用程序时,我收到了 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 线程调用。所以我在 Main 方法中添加了 [STAThread] 属性。代码现在如下所示:
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()。