星期二, 8月 10, 2010

Winform & Thread 筆記

在Winform 使用執行 Thread存取控制項,發生以下錯誤
{"跨執行緒作業無效: 存取控制項 'listBox1' 時所使用的執行緒與建立控制項的執行緒不同。"}


 private void button1_Click(object sender, EventArgs e)
       {

            ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadStart),textBox1.Text);
        }
private void ThreadStart(object path)
        {

            listBox1.Items.Clear();
            
        private void explore(string path)
        {
            try
            {
                //使用遞迴搜索所有目錄 
                foreach (string dir in Directory.GetDirectories(path))
                {
                    explore(dir);
                    listBox1.Items.Add(dir);
                }
                foreach (string file in Directory.GetFiles(path))
                {
                    fileCount++;
                    listBox1.Items.Add(file);
                    //加總檔案大小 
                    FileInfo fi = new FileInfo(file);
                    totalSize += fi.Length;
                }
            }
            catch (UnauthorizedAccessException uae)
            {
                listBox1.Items.Add("Error with :" + uae.ToString());
            }      
        } 

當thread碰到winfrom UI thread,不能用此thread去更動UI Thread 內的Control!!
所以借用︰
  1. 一個Deledgd( 對Contol 處理行為的方法)
  2. Control.Invork() (為同步呼叫,等待 delegate指向的程式執行完畢才會繼續向下走)
  3. Conrotl.BeginInvork(是非同步呼叫,呼叫後立即繼續向下執行)

//宣告委派
 delegate void UpdateConrtolFunHandar(string path); 
 //宣告Control控制項的方法
 private void funListBox(string dirName)
        {
            listBox1.Items.Add(dirName);
        }
 

//將原本的寫法用Invok呼叫,已UI Thread 執行
 this.Invoke(new UpdateConrtolFunHandar(funListBox),dir);
 //listBox1.Items.Add(dir);

Reference:

沒有留言: