如何在C#中混合两个不同线程的输出? [英] How can I mix the output of two different threads in C#?

查看:119
本文介绍了如何在C#中混合两个不同线程的输出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an application in C# which generates a series of images in the form of movie clip, which contains two methods. Each method generates a series of images (frames per second) which will display to my outputs (PictureBox_1 and PictureBox_2 accordingly).

我的问题是如何将这两个方法中的这些系列图像随机混合而不是分别播放每个线程我运行第三个线程,这是随机的混合两个其他线程?

My question is how can I mix this these series of images from two methods with each other randomly and instead of playing each thread separately I run the third thread which is the randomly mixing of two other threads?

例如输出如下:

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

Thread one: bmp1, bmp1, bmp1, …

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

Thread two: bmp2, bmp2, bmp2, …

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

Thread three; bmp1, bmp1, bmp2, bmp1, bmp2, bmp2, bmp2, bmp1, …

推荐答案

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

The obvious solution would be to push generated images from both threads into a central Queue which is read by the third thread.

要通知第三个线程有关新推送的图像,您可以使用 AutoResetEvent

To notify the third thread about new pushed images you can use 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。第三个线程读取生成的结果。

First two threads produce numbers, one thread range 1-1000 other in 2000-3000. Third thread reads the produced results.

Ofcourse而不是 int 你将使用你的Image类。

Ofcourse instead of int you would use your Image class.

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

Please note that the above code does neverEndingConsumer.Wait(); only for testing purposes. You don't want this in your code as it blocks forever.

另一个提示:如果您从消费者线程访问图片框,请不要忘记使用Invoke来编组UI访问GUI线程。

Another hint: If you access the picturebox from the consumer thread don't forget to use Invoke to marshal the UI access to the GUI thread.

这篇关于如何在C#中混合两个不同线程的输出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆