用C#代码实现线程
本文关键字:线程 实现 代码 | 更新日期: 2023-09-27 18:26:37
我想做两个线程,因为我想把第一个for循环分成两部分。我想为每个循环生成for (var row = 0; row < area.Height/2; row++)
和for (var row = area.Height/2; row < area.Height; row++)
,而不是for (var row = 0; 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个线程共享所有这些变量。
当有很多好的抽象可供选择时,不要直接使用线程。TPL是其中之一,但我更喜欢微软的反应式框架(NuGet"Rx-Main")。有了它,你可以做到这一点:
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);
});
根本不需要管理线程,但您可以获得最大并发性。