2015-09-23 16 views
6

私はWin ApiをC#で使用してDDEクライアントの機能を実装しています。私がDdeInitializeWDdeConnectをシングルスレッドで呼び出す場合は、すべて正常に動作します。 は具体的には、これらは、ラッパーの定義です:C#Win Api DDE接続マルチスレッド

[DllImport("user32.dll")] 
    protected static extern int DdeInitializeW(ref int id, DDECallback cb, int afcmd, int ulres); 

    [DllImport("user32.dll")] 
    static extern IntPtr DdeConnect(
     int idInst,    // instance identifier 
     IntPtr hszService,  // handle to service name string 
     IntPtr hszTopic,  // handle to topic name string 
     IntPtr pCC    // context data 
     ); 

私は別のスレッドでDdeInitializeWDdeConnectと呼ばれる場合は、NULLポインタを返すDdeConnect

また、1つのスレッドで両方の(確立されたDDE接続)を呼び出すと、このDDEチャネルを別のスレッドで使用することはできません(INVALIDPARAMETER DDEエラーが発生しています)。

私が言ったように、すべては問題なしでシングルスレッドで動作します。

答えて

6

あなたが記述している動作は予期されています。

DDEは個々のスレッドに関連付けられています。これは、DDE(一般的にはレガシーテクノロジと見なされます)がWindowsメッセージを渡すことで内部的に動作し、ウィンドウハンドル(HWND)がスレッド親和性を持つからです。

  • DdeConnectと同じスレッドからDdeInitializeWに電話する必要があります。
  • そのスレッドはメッセージをポンピングする必要があります(したがって、スレッドプールスレッドにすることはできません)。
  • 同じスレッドでもコールバック/応答が返されます。言い換えれば

あなたはApplication.Runを呼び出し、またはイベントが送信または受信されることが適切であるときに頻繁瞬間にApplication.DoEventsを呼び出したスレッドからあなたのDDEを行う必要があります。

複数のスレッドからDDEを使用できますが、それぞれはDdeInitializeWを呼び出す必要があり、要求が送信されたスレッドでは常に応答が受信されます。

+0

これは私がこの時点で行っていることです。これはDDE自体の問題だと私は恐れていました。それで私を保証してくれてありがとう。 – Majak

+0

また、まだやっていないのであれば、ヒント: 'DdeSetUserHandle'と' DdeQueryConvInfo'を使って、各会話に一意のIDを与えることで、複数のDDE会話を追跡してください。これにより、すべてが簡単になります。 https://msdn.microsoft.com/en-us/library/windows/desktop/ms648765(v=vs.85).aspx – Ben