【问题标题】:Forms GUI Video thread communications窗体 GUI 视频线程通信
【发布时间】:2012-01-23 11:04:15
【问题描述】:

我正在以 C# 形式创建自定义视频播放器。目前播放器有一个初始化和关闭例程,以及一个在后台运行的线程,读取视频帧并显示它们。我对 C# 相当陌生,所以我试图确定如何最好地将 start\stop\pause 命令从 GUI 线程发送到视频线程。我是否应该只使用一个受锁保护的状态变量并在我的视频线程中每次轮询它?在那里 还有其他建议吗?

谢谢。

【问题讨论】:

  • 您的帧是如何通过系统的?线程创建视频帧对象,将传入的流解码为它们并 BeginInvokes 将它们发送到 GUI?
  • 复制到非 UI 线程上的自定义 DirectShow 推送源过滤器。
  • 如果这是 DirectShow 特有的,您可能需要添加标签。

标签: c# multithreading forms user-interface


【解决方案1】:

轮询状态变量似乎是为您的视频线程提供足够定期循环的最简单的解决方案。

你甚至可能不需要锁,在 C# 中设置状态变量 volatile 就足够了,只要一个线程更新它。 (C# 中的volatile 的语义与 C 略有不同,应保证其他线程获取新值)

【讨论】:

  • 最后,我在 Start/Stop/Pause 上使用了 currentState 和 nextState 变量,因此它们只在正确的时间被激活。它的编码方式不需要任何锁(这很好)。
【解决方案2】:

有几种方法是可能的。由于您是 C# 新手并且可能与 UI 紧密耦合,我建议您使用 BackgroundWorker 类。

http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx

您可以使用 DoWork 事件的 DoWorkEventArgs 传递您的参数。 同样通过这种方法并且没有共享对象(通过线程),您可以避免使用锁定或同步

我认为这可能是您的最佳解决方案,但还有其他选择。您可以使用异步编程模型 (APM),甚至可以使用 Thread/ThreadPool 或任务并行库。

我是否应该只使用一个受锁保护的状态变量,并且每次在我的 >>video 线程中轮询它;还有其他推荐吗?

如果您有像视频线程这样的共享状态,那么您应该使用线程同步。所以,答案是肯定的,你应该使用一些受保护的变量,你可以通过使用 volatile 来避免锁定,但考虑使用其他同步原语。因为使用 volatile 只是确保您正在读取/写入大多数实际值,但不会阻止其他线程读取/写入。

一些链接可以选择是使用锁(其他原语)还是仅使用 volatile:

Do I need to lock or mark as volatile when accessing a simple boolean flag in C#?

Volatile vs. Interlocked vs. lock

【讨论】:

  • DoWorkEventArgs 仅在开始时传递。他需要在线程运行时将状态传递给线程。
  • 好的,比共享状态和线程同步。我更新我的答案
【解决方案3】:

您应该能够不受限制地调用开始/停止/暂停 DirectShow 过滤器图。这将导致对源过滤器的相应方法调用(有关更多信息,请参阅Filter States)。源过滤器确实需要通知后台线程状态变化,如果这还没有完成的话。

同步的实现方式与 DirectShow 类相同,过滤器中使用了两个AutoResetEvent 实例,一个通知后台线程有新请求,一个通知调用线程请求处理完成.

【讨论】:

    猜你喜欢
    • 2015-03-17
    • 1970-01-01
    • 1970-01-01
    • 2021-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多