c # Reactive Extension of FromEventPattern and FromEvent

Some nonsense

In doing a synchronization device reporting by FileSystemWatcherthe report generated by the monitoring device at the specified location, parse and upload.
The reason why the monitor file system, rather than a direct connection with the device software, and there will be a large section of complaint, put aside.

While monitoring file, modify events such as file creation, sometimes several times to report, this could be a file system or implementation code related, so do anti-shake.

Before the adoption of self-defined private fields / timer done anti-shake, some trouble, but not very easy to maintain, learned online Reactive Extension(corresponding to .net corethe System.Reactivepackage), image stabilization can be done, I looked for a moment to read the relevant documents.

Beginning to look confused, the main function is too much, is not the main purpose of stabilization, it is not easy to find the content (simple and straightforward example) want

text

ObservableCreated from the event, there are two ways to create FromEventPatternand FromEvent(in fact there are many, but I was involved in both), for a long time to find the relevant information ( this answer on SO helpful), and wrote some test code , finally understand about the Editor's Note.

The final code

Paste the code before the final method that can be used (in fact correct more than one way)

var watcher = new FileSystemWatcher();
watcher.Path = "d:\\test";

var observable = Observable.FromEventPattern<FileSystemEventHandler, FileSystemEventArgs>(
            ev => watcher.Changed += ev,
            ev => watcher.Changed -= ev);

var d = observable.Throttle(TimeSpan.FromSeconds(5))
    .Subscribe(
        a => Console.WriteLine($"Watcher type:{a.EventArgs.ChangeType }, file:{a.EventArgs.Name }, sender: {a.Sender}"),
        ex => Console.WriteLine("observer error:" + ex.ToString()),
        () => Console.WriteLine("observer complete.")

Observable achieve understanding

Observable Observer for binding and the Event Source delegate, his role is that some of the filtering process may be performed (personal understanding).

Observer primarily through which to achieve OnNextthis a delegate, when there is Observable event is triggered, it will call the Observer registration OnNextmethod, OnNext method is Action<T>the type, and template parameters Tfrom Observablespecified when created.

.net events

.net in the event handler in line with EventHandlerthe delegate format

public delegate void EventHandler(object sender, EventArgs e);

Two arguments, returns null.

Observable for distributed event handling observer, although events can be any custom events, but to conform to .net standard EventHandlermode event, providing FromEventPatternways to create Observable, and other custom mode event, we FromEventcreate it.

The final two are functionally equivalent, can do with FromEvent FromEventPatternfunction (requires more code), and vice versa (more trouble), I wrote a few examples to test this.

FromEvent

Both signatures (choose a generic)

//FromEvent
public static IObservable<TEventArgs> FromEvent<TDelegate, TEventArgs>
              (Func<Action<TEventArgs>, TDelegate> conversion, 
              Action<TDelegate> addHandler,
              Action<TDelegate> removeHandler);

This is a common method of creating Observable.

  • TDelegate: This is the type of event source

  • TEventArgs: This is actually OnNextthe Tparameters, rather than TDelegatethe argument , OnNextit is Action<T>, can only receive one parameter, the generic types to indicate the Observer created OnNextparameter handler need to be addressed

  • conversion: In general, TDelegateand OnNextthe signature is different, this time need a converter function that will Tdelegatetranslate into OnNextcalls

  • addHandler/removeHandler: Register and unregister event, Observercall the Subscriberegistered subscription.

    In fact, can be seen, Observablethe source of the event (in line type TDelegate) type, translate into OnNextcalls.
    To some extent, can be seen as eventthe +operation (there may be a question that why rx this layer, observer capacity is actually on the filter handling of the incident, that in the event - on the path> event handler, an increase of various functions).

FromEventPattern

//FromEventPattern
public static IObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler);

And the signature FromEventis substantially the same, except that at least one convensionconversion parameter.

This is because the function that is designed for interfacing .net standard EventHandlertypes of events. EventHandler contains two parameters senderand EventArgs, and this will function i.e. sender and EventArgs two parameters configured to a EventPattern<EventArgs>type of parameter passed to OnNext.
In other words, the internal RX has helped us achieve .net standard for the type of event EventHandler conversionconversion functions.

There are also noticed TDelegateand TEventArgstwo parameters, which helped us to expand in line with EventHandlerthe extended format type of event. The EventHandler EventArgscan be designated as TEventArgsthe type of representative, EventHandler also be extended to the appropriate EventHandler<TEventArgs>type of event format.

Sample Code

I based my original demand FileSystemWatchermonitoring, wrote some sample code to verify the use and differences.

Observable Based on the FileSystemWatcher Changedevents, Observer of the OnNextrealization of all use the same printing functions, created by different methods of Observerbal, to achieve the same purpose.

Finally, the addition of a simultaneous monitoring Changedand Renamedevent, and add code to my original anti-shake purposes.

Frame code is as follows:

//Create watcher
var watcher = new FileSystemWatcher();
watcher.Path = "d:\\test";

//creation of observable goes here
var observable = .....

//subscribe to observable
var d = observable
	.Subscribe(
		a => Console.WriteLine($"Watcher type:{a.ChangeType}, file:{a.Name}"),
		ex => Console.WriteLine("observer error:" + ex.ToString()),
		() => Console.WriteLine("observer complete.")
);			
//Enable watcher
watcher.EnableRaisingEvents = true;

FromEventPattern

Since the Changedevent in line with the signature EventHandler<FileSystemEventArgs>type, so in this way can be defined as follows observable:

var observable = Observable.FromEventPattern<FileSystemEventHandler, FileSystemEventArgs>(
                            ev => watcher.Changed += ev,
                            ev => watcher.Changed -= ev).Select(x => x.EventArgs);

Note that the final Select, it will EventPattern<FileSystemEventArgs>be converted to FileSystemEventArgs.

FromEvent

If you pass FromEvent, you will need to EventHandler<FileSystemEventArgs>translate into OnNextcalls.
If you do not use FromEvent through conversion function, create the code runs the agent fails:

//THIS IS WRONG!
var observable = Observable.FromEvent<FileSystemEventHandler, FileSystemEventArgs>(
                            ev => watcher.Changed += ev,
                            ev => watcher.Changed -= ev);

By conversion

The need to increase a conversion function transformation

var observable = Observable.FromEvent<FileSystemEventHandler, FileSystemEventArgs>(
                    handler =>
                    {
                        return (object sender, FileSystemEventArgs fa) => handler(fa);
                    }
                    , ev => watcher.Changed += ev,
                            ev => watcher.Changed -= ev);

By modifying agent type source

A little trouble, but as a showcase of use FromEvent, when the signature is the same, no need for conversion overloaded.

First, define the proxy class using observable

private delegate void MyWatcherDelegate(FileSystemEventArgs args);

private static event MyWatcherDelegate MyWatcherEvent;

Then watcher event subscription to the custom of MyWatcherEventthe event. (Note that since anonymous function is used here, it can not be removed from the Watcher event)

watcher.Changed += (sender, args) =>
                {
                    Console.WriteLine("Intermediate watcher handler delegate");
                    if (null != MyWatcherEvent)
                    {
                        Console.WriteLine("Call through custom event");
                        MyWatcherEvent(args);
                    }
                };

Finally created by FromEvent Observable, this time for MyWatcherDelegatecompliance with OnNext signature, so no conversion method can be successfully created.

var observable = Observable.FromEvent<MyWatcherDelegate, FileSystemEventArgs>(
                   ev => MyWatcherEvent += ev,
                   ev => MyWatcherEvent -= ev);

The combined Renamed and Changed events

In fact, the title here and little to do, but to expand the use of Observable.
By Mergecan simultaneously monitor different observable signatures of two events:

var o1 = Observable.FromEventPattern<FileSystemEventHandler, FileSystemEventArgs>(
                            ev => watcher.Changed += ev,
                            ev => watcher.Changed -= ev);
var o2 = Observable.FromEventPattern<RenamedEventHandler, RenamedEventArgs>(
            ev => watcher.Renamed += ev,
            ev => watcher.Renamed -= ev)
    .Select(x => new System.Reactive.EventPattern<FileSystemEventArgs>(x.Sender, x.EventArgs));

var observable = Observable.Merge(o1, o2);

Guess you like

Origin www.cnblogs.com/mosakashaka/p/12608853.html