请问,用VS2008创建一个默认的winform程序,该程序自动创建多少个线程,分别是哪些,每个线程的作用又是什么?如果我不手动明确的创建线程,在什么情况下操作控件,需要使用Invoke或BeginInvoke方法更新控件?下面这段程序时创建一个文件监视器,当所监视的文件发生变化时,就把变化情况记录下来。这段程序没有创建其它新的线程,为什么也必须通过BeginInvoke方法来更新相应的lable控件。using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;namespace FileWatch
{
    public partial class Form1 : Form
    {
        // File System Watcher object.
        private FileSystemWatcher watcher;
        private delegate void UpdateWatchTextDelegate(string newText);        public Form1()
        {
            InitializeComponent();            this.watcher = new System.IO.FileSystemWatcher();
            this.watcher.Deleted +=
               new System.IO.FileSystemEventHandler(this.OnDelete);
            this.watcher.Renamed +=
               new System.IO.RenamedEventHandler(this.OnRenamed);
            this.watcher.Changed +=
               new System.IO.FileSystemEventHandler(this.OnChanged);
            this.watcher.Created +=
               new System.IO.FileSystemEventHandler(this.OnCreate);            DirectoryInfo aDir = new DirectoryInfo(@"C:\FileLogs");
            if (!aDir.Exists)
                aDir.Create();
        }        // Utility method to update watch text.
        public void UpdateWatchText(string newText)
        {
            lblWatch.Text = newText;
        }        // Define the event handlers.
        public void OnChanged(object source, FileSystemEventArgs e)
        {
            try
            {
                StreamWriter sw =
                   new StreamWriter("C:/FileLogs/Log.txt", true);
                sw.WriteLine("File: {0} {1}", e.FullPath,
                             e.ChangeType.ToString());
                sw.Close();
                this.BeginInvoke(new UpdateWatchTextDelegate(UpdateWatchText),
                   "Wrote change event to log");
            }
            catch (IOException)
            {
                this.BeginInvoke(new UpdateWatchTextDelegate(UpdateWatchText),
                   "Error Writing to log");
            }
        }
        public void OnRenamed(object source, RenamedEventArgs e)
        {
            try
            {
                StreamWriter sw =
                   new StreamWriter("C:/FileLogs/Log.txt", true);
                sw.WriteLine("File renamed from {0} to {1}", e.OldName,
                             e.FullPath);
                sw.Close();
                this.BeginInvoke(new UpdateWatchTextDelegate(UpdateWatchText),
                   "Wrote renamed event to log");
            }
            catch (IOException)
            {
                this.BeginInvoke(new UpdateWatchTextDelegate(UpdateWatchText),
                   "Error Writing to log");
            }
        }
        public void OnDelete(object source, FileSystemEventArgs e)
        {
            try
            {
                StreamWriter sw =
                   new StreamWriter("C:/FileLogs/Log.txt", true);
                sw.WriteLine("File: {0} Deleted", e.FullPath);
                sw.Close();
                this.BeginInvoke(new UpdateWatchTextDelegate(UpdateWatchText),
                   "Wrote delete event to log");
            }
            catch (IOException)
            {
                this.BeginInvoke(new UpdateWatchTextDelegate(UpdateWatchText),
                   "Error Writing to log");
            }
        }        public void OnCreate(object source, FileSystemEventArgs e)
        {
            try
            {
                StreamWriter sw =
                   new StreamWriter("C:/FileLogs/Log.txt", true);
                sw.WriteLine("File: {0} Created", e.FullPath);
                sw.Close();
                this.BeginInvoke(new UpdateWatchTextDelegate(UpdateWatchText),
                   "Wrote create event to log");
            }
            catch (IOException)
            {
                this.BeginInvoke(new UpdateWatchTextDelegate(UpdateWatchText),
                   "Error Writing to log");
            }
        }        private void cmdBrowse_Click(object sender, EventArgs e)
        {
            if (FileDialog.ShowDialog() != DialogResult.Cancel)
            {
                txtLocation.Text = FileDialog.FileName;
                cmdWatch.Enabled = true;
            }
        }        private void cmdWatch_Click(object sender, EventArgs e)
        {
            watcher.Path = Path.GetDirectoryName(txtLocation.Text);
            watcher.Filter = Path.GetFileName(txtLocation.Text);
            watcher.NotifyFilter = NotifyFilters.LastWrite |
               NotifyFilters.FileName | NotifyFilters.Size;
            lblWatch.Text = "Watching " + txtLocation.Text;
            // Begin watching.
            watcher.EnableRaisingEvents = true;
        }
    }
}

解决方案 »

  1.   

    watcher 这个组件里面有非UI线程,它要操作UI控件的话,就要委托到UI线程里面来
    所以就要使用到BeginInvoke
      

  2.   

    watcher 这个组件里面有非UI线程,它要操作UI控件的话,就要委托到UI线程里面来 
    所以就要使用到BeginInvoke          试一下楼上的
      

  3.   

    当需要对某一UI控件进行更新时可以通过该UI控件对象的InvokeRequired属性进行判断            if (control.InvokeRequired)
                {
                     this.BeginInvoke(new UpdateWatchTextDelegate(UpdateWatchText), 
                      "Wrote change event to log"); 
                    return;
                }
    // 直接更新该UI控件对象
      

  4.   

    一般BeginInvoke出现在后台子线程要修改UI界面时,把子线程切换到UI线程,才能进行设置控件属性,跨线程不能修改其它线程创建的UI。