问题
I am using C#.I am new to reactive programming. Using reactive programming, I want to create a folder monitoring system which will invoke if folder A contains any file if yes then it will grab that file & process it and move it in Folder B. Let say, Folder A is empty first.User adds some files into folder A realtime. System detects that new files has been added & it will process it one by one or simultaneously. I am not able to understand what should I use Create or Interval and after that where will be my processing code be written Please help me
回答1:
This should be fairly close:
var query =
Observable
.Using(
() =>
{
var fsw = new FileSystemWatcher(@"C:\A");
fsw.EnableRaisingEvents = true;
return fsw;
},
fsw => Observable.FromEventPattern<FileSystemEventHandler, FileSystemEventArgs>(
h => fsw.Created += h,
h => fsw.Created -= h))
.Delay(TimeSpan.FromSeconds(0.1));
query
.Subscribe(x => File.Move(x.EventArgs.FullPath, Path.Combine(@"C:\B", x.EventArgs.Name)));
回答2:
The FileSystemWatcher
has a relatively small InternalBufferSize (8 KB by default, 64 KB max), that can be easily exceeded if a burst of file system changes happens in a short time span, and the event handlers of the FileSystemWatcher
are doing anything time consuming. The documentation gives this advice:
Keep your event handling code as short as possible.
The consequence of exceeding the buffer is severe: all buffered notifications are lost. This should be highly undesirable in most scenarios, if not outright unacceptable. So doing heavy file-moving operations synchronously on the same thread with the event invocation is something to avoid. An easy way to achieve the desirable asynchrony is by injecting a Delay
between the handler and the subscription code. A more sophisticated approach is to queue the incoming notifications, and process each file either sequentially, or with a limited concurrency. The Merge operator can be used both for queuing and for concurrency control. Here is an example¹:
IObservable<Unit> query = Observable
.Using(() =>
{
var fsw = new FileSystemWatcher(@"C:\A");
fsw.EnableRaisingEvents = true;
return fsw;
},
fsw => Observable.FromEventPattern<FileSystemEventHandler,
FileSystemEventArgs>(h => fsw.Created += h, h => fsw.Created -= h)
)
.Delay(TimeSpan.FromSeconds(0.1))
.Select(x => Observable.Defer(() => Observable.Start(() =>
{
File.Move(x.EventArgs.FullPath, Path.Combine(@"C:\B", x.EventArgs.Name));
})))
.Merge(maxConcurrent: 2);
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
Task<Unit> task = query.ToTask(cts.Token); // Start the file-watching
The Observable.Defer
+Observable.Start
combo is used as a synchronous equivalent of the asynchronous Observable.FromAsync
(because the File.Move
method is synchronous).
¹ It is a modified version of Enigmativity's example.
来源:https://stackoverflow.com/questions/49732510/file-monitoring-system-reactive-programming