1

静的イベントスレッドセーフを発生させることはできますか?(それが何を意味するのか完全にはわかりません。)すべてがオーディオアプリケーションの一部であるため、(少なくとも)オーディオ処理スレッドとUIスレッドがあります。

RaisePrintEventは、オーディオおよびその他のメッセージを処理するアンマネージCコードから呼び出されます。イベントを発生させるための呼び出しは、オーディオ処理スレッドとUIスレッドから発生する可能性があります。

public static event ProcessPrint Print = delegate {};

private static void RaisePrintEvent(string e)
{
    Print(e);
}

イベント呼び出しが同期されていることを確認するにはどうすればよいですか?または、メインスレッドで呼び出されただけかもしれません。

編集:スマートな解決策については、ここを読んでください。

4

2 に答える 2

3

UI 操作がすべてメイン/UI スレッドで実行されるようにする必要があります。

最善の方法は、メッセージをオーディオ スレッドから何らかの形式のキューにキューイングし、デキューしてメイン UI スレッド (Forms.Timerイベントなど) から表示することです。

Invoke()オーディオ処理のタイミングが崩れるため、うまくいきません。試してみて、GUI で何かをしている場合、他のスレッドで何かを Invoke() すると、他のスレッドが Invoke を実行するために使用されるウィンドウ メッセージを処理するまで BLOCK するため、おそらく音声がぎくしゃくするでしょう。フードの下'。

上記の一部またはすべてを理解していない場合は、メッセージに queue を使用してみてください。

于 2012-05-05T21:17:28.210 に答える
2

ハンドラーをローカル変数にコピーして、呼び出し中に別のスレッドがイベントのサブスクライブを解除した場合の競合状態を回避する必要があります (詳細については、こちらを参照してください)。

private static void RaisePrintEvent(string e)
{
    var handler = Print;
    if (handler != null)
    {
        handler(e);
    }
}

一度に 1 つのスレッドだけでイベントを発生させたい場合は、呼び出しをロックするだけです。

private static readonly object _printLock = new object();
private static void RaisePrintEvent(string e)
{
    lock(_printLock)
    {
        var handler = Print;
        if (handler != null)
        {
            handler(e);
        }
    }
}
于 2012-05-05T21:17:29.710 に答える