用C#代码实现线程

时间:2015-12-13 00:30:50

标签: c# multithreading

我想创建两个线程,因为我想先将for循环分成2个部分。而不是for (var row = 0; row < area.Height; row++)我希望为每个循环创建for (var row = 0; row < area.Height/2; row++)for (var row = area.Height/2; row < area.Height; row++),而我想要线程。我不知道如何实现这个东西。你能帮助我吗 ?

using System;
using System.Diagnostics;
using System.Drawing;
using System.Threading;

namespace MandelbrotGenerator {
  public class SyncImageGenerator : IImageGenerator {
    public void GenerateImage(Area area) {
      var sw = Stopwatch.StartNew();
      var bitmap = SyncImageGenerator.GenerateSyncroniously(area);
      GenerationDone(area, bitmap, sw.Elapsed);
    }

    public static Bitmap GenerateSyncroniously(Area area) { 
      int maxIterations;
      double zBorder;
      double cReal, cImg, zReal, zImg, zNewReal, zNewImg;

      maxIterations = Settings.DefaultSettings.MaxIterations;
      zBorder = Settings.DefaultSettings.ZBorder * Settings.DefaultSettings.ZBorder;

      Bitmap bitmap = new Bitmap(area.Width, area.Height);

      for (var row = 0; row < area.Height; row++) {
        for (var col = 0; col < area.Width; col++) {
          var pixelWidth = (area.MaxReal - area.MinReal) / area.Width;
          cReal = area.MinReal + col * pixelWidth;
          var pixelHeight = (area.MaxImg - area.MinImg) / area.Height;
          cImg = area.MinImg + row * pixelHeight;
          zReal = 0.0;
          zImg = 0.0;
          var iter = 0;
          while (zReal*zReal+zImg*zImg<zBorder && iter<maxIterations) {
            zNewReal = zReal * zReal - zImg * zImg;
            zNewImg = zImg * zReal + zReal * zImg;
            zNewReal = zNewReal + cReal;
            zNewImg = zNewImg + cImg;
            zReal = zNewReal;
            zImg = zNewImg;
            iter++;
          }
          bitmap.SetPixel(col, row, ColorSchema.GetColor(iter));
        }
      }

      return bitmap;
    }
    public event EventHandler<EventArgs<Tuple<Area, Bitmap, TimeSpan>>> ImageGenerated;
    private void GenerationDone(Area area, Bitmap bitmap, TimeSpan time) {
      if (ImageGenerated != null) {
        ImageGenerated(this, new EventArgs<Tuple<Area, Bitmap, TimeSpan>>(Tuple.Create(area, bitmap, time)));
      }
    }
  }
}

实际上,我不知道如何使用所有这些变量以及如何用2个线程共享所有这些变量。

1 个答案:

答案 0 :(得分:-1)

当有很多好的抽象可供选择时,不要直接使用线程。 TPL是一个,但我更喜欢微软的Reactive Framework(NuGet&#34; Rx-Main&#34;)。有了它,你可以这样做:

public static IObservable<Bitmap> GenerateAsynchronously(Area area)
{
    int maxIterations = 100;
    double zBorder = 1.0;

    var compute =
        from row in Observable.Range(0, area.Height)
        from col in Observable.Range(0, area.Width)
        from iter in Observable.Start(() =>
        {
            var pixelWidth = (area.MaxReal - area.MinReal) / area.Width;
            double cReal = area.MinReal + col * pixelWidth;
            var pixelHeight = (area.MaxImg - area.MinImg) / area.Height;
            double cImg = area.MinImg + row * pixelHeight;
            double zReal = 0.0;
            double zImg = 0.0;
            var i = 0;
            while (zReal * zReal + zImg * zImg < zBorder && i < maxIterations)
            {
                double zNewReal = zReal * zReal - zImg * zImg;
                double zNewImg = zImg * zReal + zReal * zImg;
                zNewReal = zNewReal + cReal;
                zNewImg = zNewImg + cImg;
                zReal = zNewReal;
                zImg = zNewImg;
                i++;
            }
            return i;
        })
        select new { row, col, iter };

    var query =
        from xs in compute.ToArray()
        from bm in Observable.Start(() =>
        {
            Bitmap bitmap = new Bitmap(area.Width, area.Height);
            foreach (var x in xs)
            {
                bitmap.SetPixel(x.col, x.row, ColorSchema.GetColor(x.iter));
            }
            return bitmap;
        })
        select bm;

    return query;
}

现在您要返回IObservable<Bitmap>而不是Bitmap。你这样消费:

    var bitmapObservable = SyncImageGenerator.GenerateAsynchronously(area);
    bitmapObservable
        .Subscribe(bitmap =>
        {
            GenerationDone(area, bitmap);
        });

根本不需要管理线程,但是你获得了最大的并发性。