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()-ing 其他线程上的某些东西会阻塞,直到其他线程处理用于执行 Invoke 的窗口消息'在引擎盖下'。

如果您不了解上述部分或全部内容,请尝试使用队列来接收消息。

于 2012-05-05T21:17:28.210 回答
2

您需要将处理程序复制到局部变量,以避免在您调用它时另一个线程取消订阅事件时出现竞争条件(有关详细信息,请参见此处):

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

如果您希望事件一次仅由一个线程引发,只需将调用锁定:

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 回答