Bonjour アルゴリズムを使用してネットワーク内のサービスを検索するプログラムを開発しています。Bonjour SDK for Windowsをダウンロードしました。.Net には 2 つのサンプル アプリケーションがありました。どちらも 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() を呼び出します。