新线程比主线程慢 [英] New thread slower than main thread
本文介绍了新线程比主线程慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我创建了一些方法并测试了它们是否有效,唯一的问题是GUI没有响应.
因此,我创建了一个新类,将其复制/粘贴到方法中,并使其在新线程中运行.
现在问题已解决,GUI可以正确响应,但是现在方法要花费2-3倍的时间才能完成.
希望有人能解决.
I created some methods and tested that they worked, the only problem was GUI not responding.
So i created a new class, copy/pasted in the methods and made it run in a new thread.
Now the problem was solved, GUI was responding correctly but now methods take 2-3 times longer to complete.
I hope someone has a solution.
static class ColorSmoother
{
private static bool _run;
private static byte _stepSize;
private static Thread _worker;
#region Events
public delegate void ProgressEventHandler(Bitmap bitmap);
public static event ProgressEventHandler Starting;
public static event ProgressEventHandler Step;
public static event ProgressEventHandler Done;
#endregion
static ColorSmoother()
{
_worker = new Thread(new ParameterizedThreadStart(Work));
_worker.Name = "ColorSmoother - Worker Thread";
_worker.Priority = ThreadPriority.Highest;
}
public static byte StepSize
{
get { return _stepSize; }
set { _stepSize = value; }
}
public static bool Run
{
get { return _run; }
set { _run = value; }
}
static void Work(object param)
{
Bitmap tempBitmap = (Bitmap) param;
param = null;
Run = true;
if (Starting != null)
Starting(tempBitmap);
int x,y, width = tempBitmap.Width, height = tempBitmap.Height;
Color newColor = Color.DimGray,oldColor;
for (x = 0; x < width; x++)
{
for (y = 0; y < height; y++)
{
if (!Run)
{
tempBitmap.Dispose();
return;
}
oldColor = tempBitmap.GetPixel(x, y);
newColor = GetNewColor(oldColor);
tempBitmap.SetPixel(x, y, newColor);
if (Step != null)
Step(tempBitmap);
}
}
if (Done != null)
Done(tempBitmap);
tempBitmap.Dispose();
}
internal static void SmoothImage(Bitmap newBitmap)
{
_worker = new Thread(new ParameterizedThreadStart(Work));
_worker.Start(newBitmap);
}
private static Color GetNewColor(Color oldColor)
{
Color newColor;
byte r = FindColorGroup(oldColor.R);
byte g = FindColorGroup(oldColor.G);
byte b = FindColorGroup(oldColor.B);
newColor = Color.FromArgb(r, g, b);
return newColor;
}
private static byte FindColorGroup(int color)//148
{
int groupValue = 0;
while (groupValue + StepSize < color)//97
{
groupValue += StepSize;
}
if (color - groupValue > (groupValue + StepSize) - color)
groupValue += StepSize;
if (groupValue > 255)
groupValue = 255;
return (byte)groupValue;
}
}
推荐答案
好吧,线程有它的开销,但是还有其他一些问题会影响您的性能.
切勿使用GetPixel
/SetPixel
,它太慢了! (除非您只需要1或2-3个像素:-).)如果这是System.Drawing.Bitmap
,请改用LockBits
/UnlockBits
.在此处找到代码示例:
http://msdn.microsoft.com/en-us/library/5ey6h79d.aspx [ ^ ].
您似乎忽略了各种像素格式,这是不安全的,请参见PixelFormat
.
ParameterizedThreadStart
没有任何意义!如果强迫您进行不安全的类型案例练习.您可以创建一个线程包装器,然后传递其"this"引用.请在此处查看我的代码示例:
如何将ref参数传递给线程 [ ^ ].
请参阅我过去有关将线程与UI结合使用的答案:
如何获取keydown事件在vb.net中的不同线程上操作 [启用禁用+多线程后控件事件不会触发 [ ^ ].
祝你好运,
—SA
Well, threading has its overhead, but there are other problems which compromise your performance.
Never useGetPixel
/SetPixel
, it''s too slow! (Unless you need just 1 or 2-3 pixels :-).) If this isSystem.Drawing.Bitmap
, useLockBits
/UnlockBits
instead. Find a code sample here:
http://msdn.microsoft.com/en-us/library/5ey6h79d.aspx[^].
You seemingly ignore the various Pixel Formats, this is unsafe, seePixelFormat
.
ParameterizedThreadStart
makes no sense! If forces you into unsafe practice of type case. You can create a thread wrapper and pass its "this" reference instead. Please see my code sample here:
How to pass ref parameter to the thread[^].
See my past answers on using threads with UI:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].
Good luck,
—SA
这篇关于新线程比主线程慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文