最近公司的專案遇到需要再別人將資料新增之指定資料夾時,做讀資料的判斷工作。
在處裡的過程遇到監控資料夾的問題,以及讀檔案時遇到多執行序的問題,所以來分享一下我的方法。
首先,先大概拉個介面,以下的程式中會包含程式檔名、資料夾下檔案數量。

在這裡只做讀到檔案名稱及檔案數量的工作(我工作上遇到的是圖檔,所以還得開圖處理,如果之後有遇到其他問題,解決後會再發上來)。
然後是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都共用相同的事件處理程序。
好了,以上是小弟個人的關於資料夾監控的程式撰寫心得,給大家參考,如有誤人子弟之處,還請各位先進給予指教。
如果覺得本篇文章對你有幫助的話,也請別忘記留言給予鼓勵喔。
留言列表