Been reading up on threading a bit and still looking into using your solution.
Still have a few more questions...
foreach(var path in hashset)
... do what you need...
... do what you need...
1) if it locks that hashset and then loops thru and processes
the files 1 by 1 (which could potentially take a couple minutes a file)
then wont the other threads need to sit and wait until they can obtain the lock on the hashset? For some reason to me that seems like it is defeating the purpose of using the extra thread that processes the files.
If the thread that processes the files is running and locks the hashset for 5 minutes say, and 5 more files get dropped into the IN directory causing 5 more filesystemwatcher.fileCreated events to happen, the 1st one will be waiting to obtain a lock on the hashset and the other 4 events will be waiting in line (and filling up the file system watcher buffer) won't they?
I was trying to avoid doing much work in the filesystemwatcher.fileCreated event (as many seem to suggests) to stop it from bottlenecking and filling it's buffer and cause events to get lost.
Maybe I'm missing something, but seems like if it sits there and waits for lock to become available, it could have just done the work itself.
Maybe I can alter the logic to lock hashset, get 1st file, unlock hashset, process the file, lock hashset, remove the file just processed from hashset , unlock hashset, loop again.
Does that make any sense or is this not a legit concern?
In this case, you are right.
So, I suggest you to make it different.
Create another object to be the "lock object".
privateobject hashsetLock = newobject();
... and the thread code...
hashsetToProcess = hashset;
hashset = new HashSet<string>();
// now you can already free the lock. Note that all locks must now be // to hashSetLock instead of hashset.
foreach(string item in hashsetToProcess)
... do what you need...
In this scenario, if you keep processing for 5 minutes, there is no problem, as the new hashset is no longer locked.
Sorry but just 1 last question / confirmation.
Been trying to wrap my head around the ManualResetEvent, it's new to me.
So in your code the file processing thread calls manualResetEvent.WaitOne();
to make it stop processsing and wait, then once a new file is added
(by either the file created event on the main thread or the folder
polling thread) it calls manualResetEvent.Set() in order to make
the file processing thread resume again? Is that correct.
Then the file processing thread calls manualResetEvent.Reset(); so that
next time through the loop it will stop again waiting for another thread
to signal it to resume again? Is that correct.
So the result is...the only thread that is being stopped is the file
processing thread which is preventing it from running when there are no
files to process.
Yes. The only thread that stops is the thread that calls the WaitOne.
But, one thread will stop by time (I suggested to use another ManualResetEvent, so you call otherManualResetEvent.WaitOne(60000) and you will wait or for the event to be set [at finalization] or for 60 seconds).
ManualResetEvent is one of the best sincronization objects
I have never used FileSystemWatcher (and I know very little about it) -- I always poll; mostly because I have been accessing files on remote systems, running who-knows-what operating system and I've never needed anything like near-real-time processing of new files; polling once an hour has been sufficient.
How I do that depends on the specifics of the situation.
The most general technique I use is to have a database table where I can define what files to seek:
SearchIn contains a directory to search -- e.g. \\someserver\someshare\path...
SearchFor contains a wildcarded filename -- e.g. *.csv
DeleteIt instructs the Service whether or not to delete the file once it has been processed
LastSearch contains the LastWriteTime of the newest file found, it is maintained by the Service
The Service uses a DirectoryInfo's GetFiles method to get a list of files and then checks each file's LastWriteTime to see if it is new and not currently being written to.
Many of you are now freaking out about the performance of this technique as the number of files in the directory grows, and you're correct, but when used in concert with a pro-active archiving and purging regimen this does not become a problem -- the real problem would be in allowing the number of files to grow unfettered in the first place.
.45 ACP - because shooting twice is just silly ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001
yes..and i am receiving an error: A reference to "C:\...\OUTLFLTR.DLL" could not be added.Please make sure that the file is accesible, and that it is a valid assembly or COM Component.
OUTLFLTR.DLL - is an outlook library.
Either it is a managed code DLL, then add a reference to it and use its classes as per the usual way;
or it is an unmanaged code DLL and you will need to use P/Invoke, which is hard for complex classes and structures.
Assuming it is Outlook related, I would guess it is unmanaged code.
Either way you need to know what functionality is inside and how to use it at the functional level; then figure out the API details. The normal way to do that is by getting and studying the documentation, which should come with the executable files.
When i call the procedure i received this error message: an attempt was made to load a program with an incorrect format
The procedure has a key(the first parameter) and the documentation tell me that is 16-byte-long key.I think here is the problem.
I want that my procedure to return something like this, where the text to be more words: "63 anca black"
Entry # Word Weight Hash
2133 63 -0.009834 538bd1b2ab04f2d7205a3a9dd4010528
2133 anca -0.003434 539bd1b2ab04f2d7205a3a9dd4010528
2133 black -0.020834 540bd1b2ab04f2d7205a3a9dd4010528
Do you know also how can i use a structure from a .dll?
I don't think that the key parameter is the problem.
The error message "an attempt was made to load a program with an incorrect format" let me suggest that
you try to load an 32 bit dll in an 64 bit application or the the other way round.
I rebuild the app on 32bit, but now i am receiving "unable to find an entry point named 'ms_md5' in DLL".
I locate the DLL in my \\x86\Debug.
I take dependency walker...to see what functions are in this .dll but i wasn't able to find it.
I found only MD5Init,MD5Update,MD5FInal, but MD5INIT has a parameter type = MD5_CTX.
I can use these functions, but i don;t know how to use MD5_CTX parameter.
I created a program in Visual Studio 2008 Standard. I left the namespace with standard MyProgram. I created some classes like this one
///<summary>/// A Class
// Some content
Die werden dann in Form1.Designer.cs behandelt
// ...privatevoid InitializeComponent()
// Now we are coming to the errorthis.myDerivedPanel1 = new MyProgram.MyDerivedPanel();
private MyDerivedPanel myDerivedPanel1;
At the mentioned line, Visual Studio claims to have found an error at compile time:
<quote>Error 7 The type "MyDerivedPanel" does not exist in type "MyProgram.MyProgram"
(vaguely translated from german version)
I can delete the namespace including its "." from the erroring line and all works fine. But Visual Studio Designer re-inserts the namespace every time I change something in the Designer.
Having more than one class with this problem, deleting those namespaces gets annoying.
Is that a known issue?
Is there a known solution?
Last Visit: 31-Dec-99 18:00 Last Update: 29-Sep-23 16:17