问题
Can i raise a static event thread safe? (i am not entirely sure what that even means.) The whole thing is part of an audio application, so i have (at least) the audio processing thread and the UI thread.
The RaisePrintEvent gets invoked from unmanaged C code which processes the audio and other messages. The call to raise the event can happen from the audio processing thread and the UI thread.
public static event ProcessPrint Print = delegate {};
private static void RaisePrintEvent(string e)
{
Print(e);
}
How can i make sure, that the event call is synchronized? Or maybe just invoked in the main thread..
EDIT: read on here for a smart solution.
回答1:
You must ensure that the UI operations are all executed on the main/UI thread.
Best way would be to queue the messages into some form of queue from the audio thread and dequeue and display it from main UI thread, from Forms.Timer
event, for example.
Invoke()
won't get you far because your timing in the audio processing will be broken. If you try it, and you are doing something with your GUI, you'll probably get jerking in the audio, since Invoke()-ing something on other thread will BLOCK until other thread process the window message that is used to do Invoke 'under the hood'.
If you don't understand some or all of the above, just try to use queue for the messages.
回答2:
You need to copy the handler to a local variable, to avoid a race condition when another thread unsubscribes from the event while you're calling it (see here for details):
private static void RaisePrintEvent(string e)
{
var handler = Print;
if (handler != null)
{
handler(e);
}
}
If you want the event to be raised by only one thread at a time, just put the call in a lock:
private static readonly object _printLock = new object();
private static void RaisePrintEvent(string e)
{
lock(_printLock)
{
var handler = Print;
if (handler != null)
{
handler(e);
}
}
}
来源:https://stackoverflow.com/questions/10466022/how-to-raise-a-static-event-thread-safe-in-c