2 Stimmen

C# Monitor.Wait und VB6 Nachrichtenpumpen und Ereignisse

Ich habe ein com Callable Wrapper in C# geschrieben. Der Wrapper verwendet intern ein Socket für SendAsync und ReceiveAsync. Um dies für den VB6-Code, der diesen Wrapper aufruft, synchron erscheinen zu lassen, verwende ich Monitor.Wait.

Ich kann nicht herausfinden, ob Monitor.Wait Nachrichten pumpt, während es blockiert. Laut cbrumme's Blog auf MSDN -

Ich habe bereits erwähnt, dass die Blocking einige Pumpvorgänge durchführen wird wenn es auf einem STA-Thread aufgerufen wird.
Die verwaltete Blockierung umfasst eine umstrittene Monitor.Enter, WaitHandle.WaitOne, WaitHandle.WaitAny, GC.WaitForPendingFinalizers, unser ReaderWriterLock und Thread.Join. Es schließt auch alles andere in FX ein, das diese Routinen aufruft.

Ich sehe Monitor.Wait nicht auf dieser Liste, aber er sagt auch, dass "auch alles andere in FX, das diese Routinen aufruft", dazu gehört. Ich habe Reflector verwendet, um zu sehen, ob Monitor.Wait eine dieser Routinen aufruft, und soweit ich sehen kann, tut es das nicht. Hier ist ein weiterer Artikel, den ich ebenfalls gelesen habe.

Ich konnte nichts Eindeutigeres zu diesem Thema finden und möchte daher nur bestätigen, dass diese stark vereinfacht Beispiel ist falsch:

public bool SendAndReceiveCalledFromVb6()
{
    SendRecvToken token = SendAsync();
    /// wait for receive using Monitor.Wait.
    if(!token.EndedSynchronously) Monitor.Wait(token.anObjThatGetsPulsed);
    return token.Result;
}

und dass ich mit etwas wie dem hier besser dran wäre:

public bool SendAndReceiveCalledFromVb6()
{
    SendRecvToken token = SendAsync();
    /// wait for receive using ManualResetEvent.WaitOne.
    token.aManualResetEvt.WaitOne();
    return token.Result;
}

Außerdem stelle ich fest, dass, wenn ich ein COM-Ereignis aus meinem C#-Code auslöse, der VB6-Ereignishandler im richtigen Thread ausgeführt wird. Es wäre nützlich zu wissen, ob .Net SendMessage oder PostMessage verwendet, um das Ereignis zu marshall.

Ich danke Ihnen.

0voto

nitzmahone Punkte 13384

Es ist schon eine Weile her, seit ich auf dieser Ebene graben musste, aber der beste Weg, um dies herauszufinden, ist wahrscheinlich auf unmanaged Debugging und Symbol Download in Visual Studio zu aktivieren, deaktivieren Sie "nur mein Code", setzen Sie einen Haltepunkt bei der Monitor.Wait-Aufruf, dann an den Prozess anhängen und Schritt in (lassen Sie es nehmen Sie Assembly-Ansicht). Dann können Sie einfach herumgehen und das Call-Stack-Fenster beobachten - es wird Ihnen sagen, ob SendMessage aufgerufen wird und ob irgendwelche Pumpvorgänge stattfinden. Viele dieser Arten von internen Fragen lassen sich am besten empirisch beantworten :)

0voto

Wayne Bloss Punkte 5068

Nach einigen Tests bin ich zu dem Schluss gekommen, dass die Antwort darin besteht, dass Monitor.Wait Nachrichten genauso gut pumpt wie die EventWaitHandle Wait-Methoden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X