最近公司的專案遇到需要再別人將資料新增之指定資料夾時,做讀資料的判斷工作。
在處裡的過程遇到監控資料夾的問題,以及讀檔案時遇到多執行序的問題,所以來分享一下我的方法。
首先,先大概拉個介面,以下的程式中會包含程式檔名、資料夾下檔案數量。
在這裡只做讀到檔案名稱及檔案數量的工作(我工作上遇到的是圖檔,所以還得開圖處理,如果之後有遇到其他問題,解決後會再發上來)。
然後是Code的部分
using System.IO; using System.Linq; using System.Text; using System.Windows.Forms; namespace listenFileFormApp { public partial class Form1 : Form { StringBuilder sb; DirectoryInfo dirInfo; FileSystemWatcher _watch = new FileSystemWatcher(); public Form1() { InitializeComponent(); MyFileSystemWatcher(); } private void MyFileSystemWatcher() { //設定欲監控之資料夾位置 _watch.Path = @"F:\測試區\IN"; //設定欲監控的變更類型 _watch.NotifyFilter = NotifyFilters.FileName | NotifyFilters.DirectoryName; //設定欲監控的檔案 _watch.Filter = "*.jpg"; //設定是否監控子資料夾 _watch.IncludeSubdirectories = true; //設定是否啟動元件,此部分必須要設定為 true,不然事件是不會被觸發的 _watch.EnableRaisingEvents = true; //設定觸發事件 _watch.Created += new FileSystemEventHandler(_watch_Created); } /// <summary> /// 當所監控的資料夾有建立文字檔時觸發 /// </summary> private void _watch_Created(object sender, FileSystemEventArgs e) { sb = new StringBuilder(); dirInfo = new DirectoryInfo(e.FullPath.ToString()); //使用 delegate + invoke 方式跨執行緒對label進行操作 setlbFileName(dirInfo.Name); setLbFileAmount(dirInfo.Parent.GetFiles().Count().ToString()); } public delegate void SetTextCallback(string s); /// <summary> /// 使用 delegate + invoke 方式跨執行緒對label進行操作 /// </summary> /// <param name="text"></param> private void setlbFileName(string text) { if (this.lb_fileName.InvokeRequired) { SetTextCallback d = new SetTextCallback(setlbFileName); this.Invoke(d, new object[] { text }); } else { this.lb_fileName.Text = text; } } /// <summary> /// 使用 delegate + invoke 方式跨執行緒對label進行操作 /// </summary> /// <param name="text"></param> private void setLbFileAmount(string text) { if (this.lb_fileAmount.InvokeRequired) { SetTextCallback d = new SetTextCallback(setLbFileAmount); this.Invoke(d, new object[] { text }); } else { this.lb_fileAmount.Text = text; } } } }
執行時只要往指定的資料夾內丟檔案,就會觸發監控Function。
在做檔案監控的部分其實沒遇到甚麼大問題,主要是要將資訊顯示在label時遇到多執行序的問題。
一開始我的寫法是這樣(看第七行)
private void _watch_Created(object sender, FileSystemEventArgs e) { sb = new StringBuilder(); dirInfo = new DirectoryInfo(e.FullPath.ToString()); lb_fileName.Text = dirInfo.Name; }
就遇到了錯誤訊息【System.InvalidOperationException: '跨執行緒作業無效: 存取控制項 'lb_fileName' 時所使用的執行緒與建立控制項的執行緒不同。'】
後來的解決方法就是使用 delegate + invoke 方式跨執行緒對label進行操作,
在查解決方案時,有查到另一種解決方案,是直接設定不檢查多執行序問題的方法。如下:
Form.CheckForIllegalCrossThreadCalls = false; 這方法在DEBUG開發的過程會方便很多,但真正給使用者執行時,似乎不是最安全的方法。
看來在之後還得多學習一些關於跨執行序的問題了。
說到這,因為之後監控的資料夾不會只有一個,所以當必須監控多個資料夾的情況時,建議為欲監督的每個資料夾都各建立一個FileSystemWatcher,但是讓所有的FileSystemWatcher都共用相同的事件處理程序。
好了,以上是小弟個人的關於資料夾監控的程式撰寫心得,給大家參考,如有誤人子弟之處,還請各位先進給予指教。
如果覺得本篇文章對你有幫助的話,也請別忘記留言給予鼓勵喔。