新线程比主线程慢 [英] New thread slower than main thread

查看:81
本文介绍了新线程比主线程慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一些方法并测试了它们是否有效,唯一的问题是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 use GetPixel/SetPixel, it''s too slow! (Unless you need just 1 or 2-3 pixels :-).) If this is System.Drawing.Bitmap, use LockBits/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, see PixelFormat.

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屋!

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