Solved

How to do separate threads, when using Filesystem Watcher

Posted on 2011-10-01
5
343 Views
Last Modified: 2012-05-12
I'm using filesystem watcher in a windows service to watch a folder.  The folder will get a comma delimited text file that it will have to parse and write to a sql database.  I have all that working, but I'm getting system hangs when the oncreated event is fired.  

The filesystem watch is ran in a new thread, correct?  Can I create a new thread or a new backgound worker task for my LINQ statements and sql calls?  I'm not sure how to go about this?

Here is a snipper of my code, when the oncreated is fired, it writes the text file to a main linq result list, then I go through that master list 16 times for each of my product types.  I only show two here in the snippet.

   
public partial class ImportServer : ServiceBase
		{                 
			private System.Diagnostics.EventLog eventLog1;         
			private FileSystemWatcher watcher;

			public ImportServer()         
			{
				this.ServiceName = "UnityImport";              
				this.CanHandlePowerEvent = true;             
				this.CanHandleSessionChangeEvent = true;             
				this.CanPauseAndContinue = true;             
				this.CanShutdown = true;             
				this.CanStop = true;             
				this.AutoLog = true;                         
				
				InitializeComponent();                             
				if (!System.Diagnostics.EventLog.SourceExists("UnityImportLogSource"))
					System.Diagnostics.EventLog.CreateEventSource("UnityImportLogSource", "UnityImportLog");

				eventLog1.Source = "UnityImportLogSource";
				eventLog1.Log = "UnityImportLog";         
			}          
			
			protected override void OnStart(string[] args)
			{             
				//base.OnStart(args); 
				eventLog1.WriteEntry("service started");              
				watcher = new FileSystemWatcher();
                watcher.Path = Properties.Settings.Default.watcherPath.ToString();
				watcher.Filter = "";  
				watcher.EnableRaisingEvents = true;
				watcher.Created += new FileSystemEventHandler(OnCreated);
			}          
			
			public void OnCreated(object sender, FileSystemEventArgs e) 
			{
                    eventLog1.WriteEntry("OnCreatedHit");

                    // To Read Use:
                    if (e.Name != null)
                    {
                        string thisFile = Properties.Settings.Default.watcherPath.ToString() + e.Name;
                        try
                        {
                            string[] lines = System.IO.File.ReadAllLines(thisFile);
                            string pattern = ",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))";
                            System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex(pattern);
                           
                            var mainResults = from line in lines.AsEnumerable()
                                              let data = r.Split(line.Trim(','))  
                                               where line.Length > 0                                               
                                               select data;
                                                        
                            arraytoDataTable at = new arraytoDataTable();
                            fillNIRDataTable fillDataTable = new fillNIRDataTable();

                                // BMR CORN SILAGE
                                var bmrCornResult = from bmrCorn in mainResults.AsEnumerable()
                                                    where bmrCorn[4].ToString().Contains("BMR Corn")
                                                    select bmrCorn;
                                if (bmrCornResult.Count() > 0)
                                {
                                    DataTable dtbmrCorn = at.makeDatatable(bmrCornResult.ToArray());
                                    DataAccess bmrCornWrite = new DataAccess();
                                    bmrCornWrite.UpsertUnityRaw("[dbo].[sp_updateCornSilageBMR]", dtbmrCorn, "@tableVariable");
                                    // for insert into advantage
                                    //fillNIRDataTable fillBMR = new fillNIRDataTable();
                                    AdsAccess aBMR = new AdsAccess();
                                    aBMR.UpdateNirData(fillDataTable.fillBMRCornSilageDT(dtbmrCorn));
                                }

                                // CORN SILAGE
                                var cornSResult = from cornS in mainResults.AsEnumerable()
                                                  where cornS[4].ToString().Contains("Corn Silage")
                                                  select cornS;
                                if (cornSResult.Count() > 0)
                                {
                                    DataTable dt = at.makeDatatable(cornSResult.ToArray());
                                    DataAccess cornSWrite = new DataAccess();
                                    cornSWrite.UpsertUnityRaw("[dbo].[sp_updateCornSilage]", dt, "@tableVariable");
                                    // for insert into advantage
                                    //fillNIRDataTable fillCorn = new fillNIRDataTable();
                                    AdsAccess aCorn = new AdsAccess();
                                    aCorn.UpdateNirData(fillDataTable.fillCornSilageDT(dt));
                                }

Open in new window

0
Comment
Question by:anderdw2
  • 2
  • 2
5 Comments
 
LVL 30

Accepted Solution

by:
MlandaT earned 500 total points
ID: 36899768
There is sample code here showing how you can do the actaul file processing of the detected files on another thread. http://csharp-codesamples.com/2009/02/file-system-watcher-and-large-file-volumes/. The code samples are really nice, clean and to the point.
0
 
LVL 8

Expert Comment

by:Volox
ID: 36904895
You generally don't want to be doing that much work inside of the event from the FileSystemWatcher.

I would also point out that you may want to add some code to your OnCreated event to check that the file is done being written (by whatever is placing it into that folder) and wait for it to finish if it still has the file open.  I've run into cases with large files where FileSystemWatcher will fire the event before the file is done writing and so if you do your reads at that point you only get a portion of the data.  This seems to be especially true if the process placing the file into the folder is FTPing it.
0
 

Author Comment

by:anderdw2
ID: 36905080
Thanks, I'll take a look.  And perhaps this isn't a thread issue.  What I'm noticing, if i place a file in the watcher folder, it seems to go through the process and even moves it.  However, it doesn't update any of my sql statements.  If I place the file in again and debug through the code, it works fine or if I place it in 2x without debugging. Almost as if processes are over-stepping each other.
0
 

Author Comment

by:anderdw2
ID: 36905089
This is a drag and drop scenario, so far.  Basically, we have a comma delimited file from an instrument that we drag to this folder, it processes it and places it into a database.   I'd like to eventually FTP.

So far, the files are like 2k for our testing and they should never be more than 100k each.  However, I could still see FTP beling an issue.
0
 
LVL 30

Expert Comment

by:MlandaT
ID: 36905371
@Volox... I agree with you. I've also had some issues with large files, and incidentally, these files were being dumped into my watch folder via FTP. I came up with a scheme where when the file was created and my watcher first became aware of it, I kept a structure with the FileSize and LastModified time. I only then processed the files only after their size didnt change in a couple of seconds. I used a FileSystemWatcher to detect new files and changes etc, but also ran a timer (on a seperate thread) that polled the files every few seconds - wasnt a problem for me because the files were not dumped too fast and I could pull this kind of stunt. The timer would then queue files that hadnt changed for further processing. I'll dig around and see if I still have that code... it was literally more than 5 years ago.
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Suggested Solutions

Extention Methods in C# 3.0 by Ivo Stoykov C# 3.0 offers extension methods. They allow extending existing classes without changing the class's source code or relying on inheritance. These are static methods invoked as instance method. This…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now