小弟求解,关于线程与委托

vick3788 2014-03-25 10:52:18
写了一段程序,用于搜索文件并将它们显示在listview之中,当用单线程方式时,程序会在搜索的时候导致窗口“锁住”,也就是不能进行窗口操作,包括listview的实时更新与窗口大小的调整。于是加入的多线程,但是为什么调用了多线程后依然没有任何效果,还是“锁住”,请问是我电脑的问题吗?还是我压根就没有实现多线程。
 public partial class Form1 : Form
{
string search;
delegate void setList();
setList set = null;
public Form1()
{
InitializeComponent();

}
private void Search()
{
set = delegate()
{

listView1.Clear();
search = textBox1.Text;
//searchFile(@"C:\WINDOWS\system32");
DirectoryInfo di = new DirectoryInfo(@"C:\WINDOWS\system32");
FileInfo[] f = di.GetFiles(search);
foreach (FileInfo fi in f)
listView1.Items.Add(fi.Name);
};
listView1.Invoke(set);

}
private void button2_Click(object sender, EventArgs e)
{

Thread t = new Thread(new ThreadStart(Search));
t.Start();
}
...全文
197 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
JiaoPengJay 2014-03-25
  • 打赏
  • 举报
回复

 private void button1_Click(object sender, EventArgs e)
        {
            Thread t = new Thread(new ThreadStart(Search));
            t.IsBackground = true;
            t.Start();
        }
xingeddx 2014-03-25
  • 打赏
  • 举报
回复
        string search;
        delegate void setList(FileInfo fi);
        setList set = null;
        public Form1()
        {
            InitializeComponent();

        }
        private void Search()
        {

            listView1.Clear();
            search = @"*.*";
            //searchFile(@"C:\WINDOWS\system32");
            DirectoryInfo di = new DirectoryInfo(@"C:\WINDOWS\system32");
            FileInfo[] f = di.GetFiles(search);
            set = delegate(FileInfo fi)
                    {
                        listView1.Items.Add(fi.Name);
                    };
            foreach (FileInfo fi in f)
            {
                listView1.Invoke(set, new object[] { fi});
                Thread.Sleep(10);
            }

            

        }

        private void button1_Click(object sender, EventArgs e)
        {
            Thread t = new Thread(new ThreadStart(Search));
            t.Start();
        }
    }
xingeddx 2014-03-25
  • 打赏
  • 举报
回复
string search; delegate void setList(FileInfo fi); setList set = null; public Form1() { InitializeComponent(); } private void Search() { listView1.Clear(); search = @"*.*"; //searchFile(@"C:\WINDOWS\system32"); DirectoryInfo di = new DirectoryInfo(@"C:\WINDOWS\system32"); FileInfo[] f = di.GetFiles(search); set = delegate(FileInfo fi) { listView1.Items.Add(fi.Name); }; foreach (FileInfo fi in f) { listView1.Invoke(set, new object[] { fi}); Thread.Sleep(10); } } private void button1_Click(object sender, EventArgs e) { Thread t = new Thread(new ThreadStart(Search)); t.Start(); } }
vick3788 2014-03-25
  • 打赏
  • 举报
回复
 string textName;
        public Form1()
        {
            InitializeComponent();
            
        }
        private delegate void SetList();
        private void Search()
        {
            textName = textBox1.Text;
            if (listView1.InvokeRequired)
            {
                SetList set = new SetList(Search);
                this.listView1.Invoke(set);
            }
            else
            {
                DirectoryInfo di = new DirectoryInfo(@"C:\WINDOWS\system32");
                FileInfo[] fi = di.GetFiles(textName);
                foreach (FileInfo f in fi)
                    listView1.Items.Add(f.Name);
             
            }
        }
        private void button2_Click(object sender, EventArgs e)
        {
            Thread t = new Thread(new ThreadStart(Search));
            t.Start();
        }
新写的也是没有效果,这线程明显不给力啊
  • 打赏
  • 举报
回复
在循环里面Invoke,而不是在Invoke里面循环
        private void Search()
        {
            listView1.Clear();
            search = textBox1.Text;
            //searchFile(@"C:\WINDOWS\system32");
            DirectoryInfo di = new DirectoryInfo(@"C:\WINDOWS\system32");
            FileInfo[] f = di.GetFiles(search);
            foreach (FileInfo fi in f)
                listView1.Invoke(new Action<string>(x => listView1.Items.Add(x)), fi.Name);
        }
bigbaldy 2014-03-25
  • 打赏
  • 举报
回复
引用 2 楼 vick3788 的回复:
引用 1 楼 u011182647 的回复:
线程不能直接操作主界面啊 这个时候就用委托
我没有直接调用啊, 这不是用委托了吗?没有出现“无法调用非本线程的控件”的错误,怎么办。。。
di.GetFiles(search);这步耗时,可是你把这步也放到Invoke里面了,只需要把 listView1.Items.Add(fi.Name);放到Invoke即可,还有,如果文件多的话,你这样add也慢,用addrange方法或者调用类似beginupdate,endupdate之类的方法,把add过程放在中间,这样界面可以最后统一绘制,而不是插入一条绘制一条
a121984376 2014-03-25
  • 打赏
  • 举报
回复
你这段代码没什么问题啊~~ 是不是填充listview的一瞬间造成的堵塞~~??
vick3788 2014-03-25
  • 打赏
  • 举报
回复
引用 1 楼 u011182647 的回复:
线程不能直接操作主界面啊 这个时候就用委托
我没有直接调用啊, 这不是用委托了吗?没有出现“无法调用非本线程的控件”的错误,怎么办。。。
小恒丶 2014-03-25
  • 打赏
  • 举报
回复
线程不能直接操作主界面啊 这个时候就用委托
有道无术 2014-03-25
  • 打赏
  • 举报
回复
用委托。,给你几句你看看。。
        public delegate void RemoveItem(ListViewItem item);
        void RemoveListItem(ListViewItem item)
        {
            listView_tid.Items.Remove(item);
        }
                                RemoveItem remove = new RemoveItem(RemoveListItem);
                                this.Invoke(remove, new object[] { item });

110,571

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧