如何在C#中混合两个不同线程的输出?

时间:2014-03-18 15:50:22

标签: c# image random

我在C#中有一个应用程序,它以影片剪辑的形式生成一系列图像,其中包含两种方法。每种方法都会生成一系列图像(每秒帧数),这些图像将显示到我的输出(相应的PictureBox_1和PictureBox_2)。

我的问题是如何将这两个方法中的这些系列图像相互混合,而不是单独播放每个线程我运行第三个线程,即随机混合另外两个线程?

例如输出如下:

线程一:bmp1,bmp1,bmp1,...

线程二:bmp2,bmp2,bmp2,...

线程三; bmp1,bmp1,bmp2,bmp1,bmp2,bmp2,bmp2,bmp1,...

2 个答案:

答案 0 :(得分:4)

显而易见的解决方案是将生成的图像从两个线程推送到中央队列,由第三个线程读取。

要通知第三个主题有关新推送图像的信息,您可以使用AutoResetEvent


确定一个快速示例。

  class Program
  {
    static ConcurrentQueue<int> _centralQueue = new ConcurrentQueue<int>();
    static AutoResetEvent _signaller = new AutoResetEvent(false);

    static void Main(string[] args)
    {
      Task.Factory.StartNew(() => Producer1Thread());
      Task.Factory.StartNew(() => Producer2Thread());

      var neverEndingConsumer = Task.Factory.StartNew(() => ConsumerThread());
      neverEndingConsumer.Wait();
    }

    static void Producer1Thread()
    {
      for (int i=2000; i<3000; i++)
      {
        _centralQueue.Enqueue(i);
        _signaller.Set();          
        Thread.Sleep(8);
      }
    }

    static void Producer2Thread()
    {
      for (int i = 0; i < 1000; i++)
      {
        _centralQueue.Enqueue(i);
        _signaller.Set();
        Thread.Sleep(10);
      }
    }

    static void ConsumerThread()
    {
      while (true)
      {
        if (_centralQueue.IsEmpty)
        {
          _signaller.WaitOne();
        }
        int number;
        if (_centralQueue.TryDequeue(out number))
        {
          Console.WriteLine(number);
        }        
      }
    }
  }

前两个线程产生数字,一个线程在2000-3000之间的范围为1-1000。第三个线程读取生成的结果。

当然而不是int,你会使用你的Image类。

请注意,上述代码neverEndingConsumer.Wait();仅用于测试目的。您不希望在代码中使用它,因为它会永久阻止。

另一个提示:如果您从使用者线程访问图片框,请不要忘记使用Invoke来封送对GUI线程的UI访问。

答案 1 :(得分:1)

您可以使用ThreadPool WorkerThread生成yout图像。您在ThreadPool-Thread中提供的顺序必须与处理它们的顺序不同。

这似乎有点随意......

未经过测试或编译,只是伪代码:

QueueUserWorkItem(()=>
{
    // code that generates the image
    var img = GenerateImage();
    // set image to PictureBox via SynchronizationContext of the UI-Thread
    formSyncContext.Send(()=> pb.Image = img);
}