File Monitoring System Reactive Programming

余生长醉 提交于 2021-02-19 07:39:18

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!