自定义用户控件中的线程 [英] Threading in custom Usercontrol

查看:146
本文介绍了自定义用户控件中的线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

亲爱的所有人,
我正在一个设计应用程序中工作,我需要在其中应用线程,因为其中一个部分显示了该文件夹的所有图像的列表,该列表中的大多数都将UI挂起.所以我正在使用线程来解决这个问题.

我有一个自定义控件(继承FlowLayoutPanel),该控件显示从100 x 100(例如)大小的文件夹中选择的图像.我需要使用多线程显示这些图像.

自定义控件类:-

Dear All,
I am working on a designing application in which i need to apply threading since one section displays list of all the images of the folder which on high count hangs the UI. so i am using threading to solve this problem.

I have a custom made control(inheriting FlowLayoutPanel) which displays the images selected from a folder in size of 100 x 100(say). I need to display these images using multi-threading.

Custom Control Class:-

public partial class DesignListView : FlowLayoutPanel
    {
        public DesignListView()
        {
            InitializeComponent();
        }
        private List<String> fileList;
        public List<String> FileList
        {
            get
            {
                return this.fileList;
            }
            set
            {
                this.fileList = value;
                PopulateThumbnailInThread();
            }
        }
        public void PopulateThumbnailInThread()
        {
            Thread t = new Thread(new ThreadStart(PopulateThumbnails));
            t.IsBackground = true;
            t.Start();
        }
        public void PopulateThumbnails()
        {
            this.SuspendLayout();
            this.Controls.Clear();
            this.ResumeLayout();
            if (fileList == null)
                return;
            for (int i = 0; i < fileList.Count; ++i)
            {
                ThumbnailDisplayControl tdc = new ThumbnailDisplayControl(fileList[i]);
                tdc.MouseDown += new MouseEventHandler(tdc_MouseDown);
                AddControl(tdc);
            }
        }
        public delegate void AControl(ThumbnailDisplayControl tdc);
        public void AddControl(ThumbnailDisplayControl tdc)
        {
            if (tdc.InvokeRequired)
            {
                tdc.BeginInvoke(new AControl(AddControl), new object[] { tdc });
                return;
            }
                this.Controls.Add(tdc);
        }
        void tdc_MouseDown(object sender, MouseEventArgs e)
        {
            //Displays the selected design
        }
        
        public event DesignSelectedEventHandler DesignSelected;
        protected virtual void OnDesignSelected(DesignSelectedEventArgs e)
        {
            if (DesignSelected != null)
                DesignSelected(this, e);
        }
        
    }
    public class ThumbnailDisplayControl : PictureBox
    {
        // provides image with design and its name.
    }
    public class DesignSelectedEventArgs : EventArgs
    {
        // delegate properties n stuffs
    }
    public delegate void DesignSelectedEventHandler(object sender, DesignSelectedEventArgs e);



当前我遇到了问题:
跨线程操作无效:从创建该线程的线程以外的线程访问"designListView1"控件.

需要知道:-
.我可以在此类中调用线程[PopulateThumbnailInThread()]还是应该在主类中调用线程
.谁能建议我该怎么办?

我们将不胜感激.



Currently i am having problem :
Cross-thread operation not valid: Control ''designListView1'' accessed from a thread other than the thread it was created on.

Need to Know:-
. Can i call the thread [PopulateThumbnailInThread()] in this class or should i call the thread in Main Class
. Can anyone suggest what should i do?

Any Help will be appreciated.

推荐答案

您无需在自定义控件中添加任何线程安全功能.无论如何,非UI线程不能调用任何UI方法或属性.尽管如此,仍可以从非UI线程使用UI,但是使用线程间调用功能将调用分派到UI线程.

代替直接调用,您需要使用System.Windows.Threading.DispatcherInvokeBeginInvoke方法(对于Forms或WPF)或System.Windows.Forms.Control(仅对于Forms).

在我过去的答案中,您将找到有关其工作原理的详细说明和代码示例:
Control.Invoke()与Control.BeginInvoke() [ ^ ],
Treeview Scanner和MD5的问题 [如何获取keydown事件在vb.net中的不同线程上操作 [启用禁用+多线程后控件事件不会触发 [ ^ ].

—SA
You don''t need to add any thread-safe features in the custom controls. Anyway, a non-UI thread cannot call any UI methods or properties. Working with UI from the non-UI thread is nevertheless possible, but the calls are dispatched to the UI thread using inter-thread invocation feature.

Instead of direct calls, you need to use the method Invoke or BeginInvoke of System.Windows.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].

See also more references on threading:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].

—SA


我建​​议您不要为每个文件创建一个控件.似乎没有必要,该列表可以管理所有条目和绘制自身,这将为您节省大量创建控件时使用的窗口句柄和时间/内存.您不需要在单独的线程中进行显示,它应该不会那么慢.

您可以在我的文章中查看如何制作类似列表的用户控件(在WinForms中): LineEditor控件–基于行视觉输入/输出 [^ ] .

另外,是否有原因您不能仅为此使用ListView?您尝试执行的操作(包含项目和图像的列表)听起来与ListView的操作非常相似.

至于您提出的具体问题,请参阅SA的解决方案.
I recommend that you don''t create one control per file. That seems unnecessary, the list can manage all the entries and painting itself, which will save you a lot of window handles and time/memory used in creating controls. You should not need to do the display in a separate thread, it should not be that slow.

You can see how to make a list-like user control (in WinForms) in my article here: LineEditor Control – Line based visual input/output[^].

Also, is there a reason you can''t just use the ListView for this? What you are trying to do (a list with items and images) sounds very similar to what the ListView will do.

As for the specific question you asked, refer to SA''s solution.


这篇关于自定义用户控件中的线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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