4

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() を呼び出します。

4

1 に答える 1