AutoResetEvent Reset Method

super simple question, but I just wanted to clarify. I want to restart the stream using AutoResetEvent, so I call the following sequence of methods in my AutoResetEvent.

setupEvent.Reset(); setupEvent.Set(); 

I know this is really obvious, but MSDN does not state in its documentation that the Reset method restarts the stream, it just sets the event state without signaling.

UPDATE:

Yes, another thread is waiting in WaitOne (), I assume that when it is called, it will resume at the exact point where it stopped, which I don’t want, I want it to restart from the very beginning, The next example from this valuable The resource illustrates this:

 static void Main() { new Thread (Work).Start(); _ready.WaitOne(); // First wait until worker is ready lock (_locker) _message = "ooo"; _go.Set(); // Tell worker to go _ready.WaitOne(); lock (_locker) _message = "ahhh"; // Give the worker another message _go.Set(); _ready.WaitOne(); lock (_locker) _message = null; // Signal the worker to exit _go.Set(); } static void Work() { while (true) { _ready.Set(); // Indicate that we're ready _go.WaitOne(); // Wait to be kicked off... lock (_locker) { if (_message == null) return; // Gracefully exit Console.WriteLine (_message); } } } 

If I understand this example correctly, pay attention to how the main thread resumes where it stopped when the worker thread signals this, but in my case, I would like the main thread to restart from the beginning.

UPDATE 2:

@Jaroslav Jandek - It's pretty complicated, but basically I have a CopyDetection thread that launches FileSystemWatcher to control the folder for any new files that are moved or copied to it. My second thread is responsible for replicating the structure of this particular folder to another folder. Therefore, my CopyDetection thread should block this thread while the copy / move operation is in progress. When the operation completes, the CopyDetection stream restarts the second stream so that it can duplicate the folder structure with recently added files.

UPDATE 3:

@ SwDevMan81 - I really didn’t think about it, and that would work for one caveat. In my program, the original folder that is duplicated is cleared after the duplication process is complete. Therefore, I have to block and restart the second thread when new items are added to the original folder, so it may be possible to correctly analyze the new folder structure.

To solve this problem, I think it is possible to add a flag that signals that it is safe to delete the contents of the original folder. I think I could put the delete operation in my own cleanup thread.

@Jaroslav Jandek - My apologies, I thought it would be easy to restart the stream on a whim. To answer your questions, I do not delete the original folder, only its contents, this is a requirement of my employer, unfortunately, I can not change. Files in the source folder are moved, but not all of them, only files that are properly scanned by another process, the rest must be cleaned, that is, the source folder is empty. In addition, the reason for the replication of the source folder structure is that some files are contained in a very strict hierarchy of subfolders that must be stored in the destination directory. Again it is a pity that this has become complicated. All of these mechanisms in place, have been tested and work, so I did not feel the need to develop them. I only need to detect when new files are added so that I can stop other processes normally during the copy / move operation, then I can safely replicate the structure of the source folder and resume processing.

+4
source share
3 answers

So, thread 1 and thread 2 monitors are replicated, while other processes modify the monitored files.

Parallel access to the file aside, you will not be able to continue replication after the change. Thus, successful replication occurs only when there is a sufficiently long delay between the changes. Replication cannot be stopped immediately because you are replicating chunks.

Thus, the monitoring result should be a command (copy a file, delete a file, move a file, etc.). Successful replication should result in command execution.

Given that several operations can be performed, you need a queue (or a dictionary in a queue - only to execute 1 command in a file) of commands.

 // T1: somethingChanged(string path, CT commandType) { commandQueue.AddCommand(path, commandType); } // T2: while (whatever) { var command = commandQueue.Peek(); if (command.Execute()) commandQueue.Remove(); else // operation failed, do what you like. } 

Now you can ask how to create a thread-safe request, but this probably relates to another question (there are many implementations on the Internet).

EDIT (non-queued version with full replication dir - can be used with a request): If you do not need several operations (for example, always replicating the entire directory) and expect that replication will always be completed or fail and cancel, you can do:

 private volatile bool shouldStop = true; // T1: directoryChanged() { // StopReplicating shouldStop = true; workerReady.WaitOne(); // Wait for the worker to stop replicating. // StartReplicating shouldStop = false; replicationStarter.Set(); } // T2: while (whatever) { replicationStarter.WaitOne(); ... // prepare, throw some shouldStops so worker does not have to work too much. if (!shouldStop) { foreach (var file in files) { if (shouldStop) break; // Copy the file or whatever. } } workerReady.Set(); } 
+1
source

I think this example explains (I don't care) how reset events work:

 var resetEvent = new ManualResetEvent(false); var myclass = new MyAsyncClass(); myclass.MethodFinished += delegate { resetEvent.Set(); }; myclass.StartAsyncMethod(); resetEvent.WaitOne(); //We want to wait until the event fires to go on 

Suppose MyAsyncClass fires this method on another thread and fires the event when it is complete.

This basically turns the asynchronous "StartAsyncMethod" into synchronous. Many times I find a real-life example more useful.

The main difference between AutoResetEvent and ManualResetEvent is that using AutoResetEvent does not require a call to Reset (), but it automatically sets the state to false. The next call to WaitOne () when the false or reset () state was called.

0
source

You just need to make it a loop, as in another topic. Is this what you are looking for?

  class Program { static AutoResetEvent _ready = new AutoResetEvent(false); static AutoResetEvent _go = new AutoResetEvent(false); static Object _locker = new Object(); static string _message = "Start"; static AutoResetEvent _exitClient = new AutoResetEvent(false); static AutoResetEvent _exitWork = new AutoResetEvent(false); static void Main() { new Thread(Work).Start(); new Thread(Client).Start(); Thread.Sleep(3000); // Run for 3 seconds then finish up _exitClient.Set(); _exitWork.Set(); _ready.Set(); // Make sure were not blocking still _go.Set(); } static void Client() { List<string> messages = new List<string>() { "ooo", "ahhh", null }; int i = 0; while (!_exitClient.WaitOne(0)) // Gracefully exit if triggered { _ready.WaitOne(); // First wait until worker is ready lock (_locker) _message = messages[i++]; _go.Set(); // Tell worker to go if (i == 3) { i = 0; } } } static void Work() { while (!_exitWork.WaitOne(0)) // Gracefully exit if triggered { _ready.Set(); // Indicate that we're ready _go.WaitOne(); // Wait to be kicked off... lock (_locker) { if (_message != null) { Console.WriteLine(_message); } } } } } 
0
source

Source: https://habr.com/ru/post/1343216/


All Articles