利用FileSystemWatcher監控ASP.Net的檔案作業

  • 959
  • 0

利用ASP.Net的程式碼呼叫SAP BusinessObject的API,將Crystal Report Viewer Web Control的內容輸出成為html檔案時,由於UI Thread將檔案輸出作業交由IO Thread執行之後,將會繼續執行當下的副程式中尚未完成的程式碼指令,倘若IO Thread尚未完成檔案輸出作業,可是UI Thread卻開始載入html檔案,將會發生FileNotFound的例外,此時,除了凍結UI Thread之外,尚可利用FileSystemWatcher簡化監控資料夾與檔案的作業。

之前利用ASP.Net的程式碼呼叫SAP BusinessObject的API,將Crystal Report Viewer Web Control的內容輸出成為html檔案時,由於UI Thread將檔案輸出作業交由IO Thread執行之後,將會繼續執行當下的副程式中尚未完成的程式碼指令,倘若IO Thread尚未完成檔案輸出作業,可是UI Thread卻開始載入html檔案,將會發生FileNotFound的例外,此時,除了凍結UI Thread之外,尚可利用FileSystemWatcher簡化監控資料夾與檔案的作業。

以下以File.Create()方法產生txt檔,以模擬BusinessObject輸出html檔案的過程。

第一、凍結UI Thread直至IO Thread完成輸出Html的作業之後,再由UI Thread繼續載入Html檔案。

        protected void CreateFileButton_Click(object sender, EventArgs e)
        {

            string strFileName = this.TimeStamp();
            string strPathFileName = Server.MapPath(@".\App_Data\Temp\") + strFileName + ".txt";

            File.Create(strPathFileName);

            int i = 1;

            List<string> FileList = (List<string>)Application["Files"];
            while(!FileList.Exists(x=>x.Equals(strPathFileName)))
            {

                System.Threading.Thread.Sleep(i * 1000);
                i += 1;
            }

            if(FileList.Exists(x => x.Equals(strPathFileName)))
            { 

                foreach(string FileName in FileList)
                { 
                    Response.Write(FileName);
                    Response.Write("<br/>");
                }

                Response.Write(i.ToString() + "<br/>");
            }
        }

第二、在Global.asax中利用FileSystemWatcher監控資料夾與檔案:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;

using System.IO;
using System.Web.UI;

namespace FileSystemWatcherTest
{
    public class Global : System.Web.HttpApplication
    {
        protected void Application_Start(object sender, EventArgs e)
        {

            FileSystemWatcher fsw = new FileSystemWatcher(Server.MapPath(@"./App_Data/Temp/"));
            Application.Add("myfsw", fsw);
            // Add event handlers here
            fsw.Created += Fsw_Created;
            fsw.EnableRaisingEvents = true;

            Application.Add("Files", new List<string>());
        }
        
        private void Fsw_Created(object sender, FileSystemEventArgs e)
        {

            //Response.WriteFile(e.FullPath);

            //ClientScriptManager clientScriptManager = Page.ClientScript;
            //string scriptText = "window.open('Print.aspx');";
            //clientScriptManager.RegisterClientScriptBlock(this.GetType(), "MyScript", scriptText, true);
            
            
            List<string> FileList = (List<string>)Application["Files"];
            /*
            foreach (string file in FileList)
            {

                Response.Write(file);
                Response.Write("<br>");
            }
            */
            
            FileList.Add(e.FullPath);
            Application["Files"] = FileList;
            
            
            //throw new NotImplementedException();
        }

        protected void Application_End(object sender, EventArgs e)
        {

            FileSystemWatcher fsw = (FileSystemWatcher)Application["myfsw"];
            Application.Remove("myfsw");
            fsw.Dispose();
        }
    }
}

參考資料:
[1]Extending FileSystemWatcher to ASP.NET
http://www.developerfusion.com/article/84362/extending-filesystemwatcher-to-aspnet/

[2]FileSystemWatcher Tips
http://weblogs.asp.net/ashben/31773

[3]Monitoring File System using FileSystemWatcher Class
http://www.c-sharpcorner.com/article/monitoring-file-system-using-filesystemwatcher-class-part1/
http://www.c-sharpcorner.com/article/monitoring-file-system-using-filesystemwatcher-class-part2/

[4]How to Monitor File System Changes in C#
https://sammoreira.wordpress.com/2009/02/27/how-to-monitor-file-system-changes-in-c/

範例程式碼下載網址:
https://1drv.ms/u/s!AtXzrT02xf2jhH7xXcHYgbSAOh76