Chapter 6. CLR Integration and Scheduling

This chapter will cover two very important aspects of reactive programming: the ability to configure how time changes within the sequences and their workers (observers/observables) and the ability to interact with all the other elements of the classic CLR, such as events, threads, tasks, and so on. Here's a short index:

  • Sourcing from CLR events
  • Threading integration
  • Asynchronous sourcing
  • Time scheduling
  • Advanced time scheduling

Sourcing from CLR events

An event is the occurrence of something we can handle somehow with our code. More precisely, in .NET, an event is a kind of Delegate object, an object that represents one or multiple actions to run. The Delegate object is the .NET implementation of the Observer pattern with the addition of other features, such as asynchronous execution.

By convention, any event in .NET uses the Delegate implementation specific to System.EventHandler or any other childhood according to the inheritance tenet. This implementation accepts handlers (subscribers) that must accept two parameters, such as the following example:

static void EventHandler1(object o, EventArgs e) 
{ 
    Console.WriteLine("Handling for object {0}", o); 
} 

In place of using the generic EventArgs type as an event parameter as specified by the EventHandler delegate, when using the related generic version EventHandler<T>, we can use any other type as an argument parameter.

By using reactive programming, we can handle events or produce events to interact with classic .NET desktop/mobile applications or server-side workflow/web applications in a simplified way, producing or sourcing events from an observable sequence. In the following section, we will divert all the main operators that help us in this absolutely useful task

FromEventPattern

By using the FromEventPattern extension method of the Observable class, we can produce a sequence of the EventPattern messages containing the firing event parameters as the sender and the argument. Here's a complete example for console applications:

public static event EventHandler userIsTiredEvent; 
static void Main(string[] args) 
{ 
    //raise the event in 5 seconds 
    Task.Factory.StartNew(() => 
    { 
        Thread.Sleep(5000); 
 
        //check event is handled 
        if (userIsTiredEvent != null) 
            userIsTiredEvent("Program.Main", new EventArgs()); 
    }); 
 
    //classic event handler registration 
    userIsTiredEvent += EventHandler1; 
 
    //reactive registration 
    var eventSequence = Observable.FromEventPattern(typeof(Program), 
    "userIsTiredEvent"); 
 
    //some output 
    eventSequence.Materialize().Subscribe(x => Console.WriteLine("From Rx: {0}", 
    x)); 
 
    Console.ReadLine(); 
} 
 
static void EventHandler1(object o, EventArgs e) 
{ 
    Console.WriteLine("Handling for object {0}", o); 
} 

The FromEventPattern operator wraps events into EventPattern<T> that will flow as usual in an observable sequence. In the preceding example, we wrapped the EventPattern message into the Notification message (with the Materialize operator) to receive details about the message's type, as you learned to do in Chapter 5, Debugging Reactive Extensions .

With our code, we created two subscribers to userIsTiredEvent; one outputs the result directly to the console as it is usually done by any event handler, while the second subscriber is totally created and handled by the implementation of the FromEventPattern method.

In the nonreactive world, we're used to seeing one or more handlers per event because event delegates support multiple subscribers (bear in mind that it's an implementation of the Observable pattern). However, we rarely see a single handler handling multiple events. On the other hand, in the Rx world, it's absolutely usual to share handlers with a pipeline of sequences that may use the EventPattern parameters to make needed decisions.

Here's a complete example for a Windows Presentation Foundation (WPF) desktop application. The following code examples focus only on single application portions to explain event bridging to Rx. The full example is available with the other examples.

The UI XAML codes are as follows:

<Grid> 
    <DockPanel> 
        <UniformGrid Rows="1" DockPanel.Dock="Top"> 
            <Button Content="- 10" Command="{Binding ChangeValueCommand}" CommandParameter="-10" /> 
            <Button Content="- 1" Command="{Binding ChangeValueCommand}" CommandParameter="-1" /> 
            <Button Content="+ 1" Command="{Binding ChangeValueCommand}" CommandParameter="+1" /> 
            <Button Content="+ 10" Command="{Binding ChangeValueCommand}" CommandParameter="+10" /> 
        </UniformGrid> 
 
        <Grid> 
            <Viewbox> 
                <TextBlock Text="{Binding Result}" /> 
            </Viewbox> 
        </Grid> 
    </DockPanel> 
</Grid> 

This XAML will produce a view similar to the following screenshot:

FromEventPattern

A command based simple UI in WPF

The WPF application has a specific command: CommandBinding pattern for implementing events that support natively the Model View ViewModel (MVVM) pattern. Different from the classic .NET event pattern, the command-binding pattern supports the N-N association between command raisers and handlers. Differently, in the .NET event pattern, only the event owner can raise the event, while multiple subscribers may exist.

In the following code, we will register a single command (the event definition) with multiple button subscribers (the event raisers) and a single command-binding (the event handler):

public MainWindow() 
{ 
    InitializeComponent(); 
    DataContext = this; 
 
    //command definition 
    ChangeValueCommand = new RoutedCommand(Guid.NewGuid().ToString(), 
    typeof(MainWindow)); 
    //command binding registration 
    CommandBindings.Add(new CommandBinding(ChangeValueCommand, 
    OnChangeValueCommand)); 
} 
 
public event PropertyChangedEventHandler PropertyChanged; 
 
//classic WPF implementation 
private void OnChangeValueCommand(object sender, ExecutedRoutedEventArgs e) 
{ 
    Result += Convert.ToInt32(e.Parameter); 
    //notify value update 
    Notify("Result"); 
} 

The preceding example is pretty simple. We passed a numeric value as a command parameter from the view (the XAML) and we added/subtracted such a value parameter to/from the Result property that is visible as a label in the middle of the view.

Tip

The preceding code uses the MVVM pattern. To keep it short, we flattened the ViewModel and the View classes into a single class. Because this book focuses on reactive programming, if something is not clear here, kindly read more about MVVM by referring to a more specific book or the Internet as follows: https://msdn.microsoft.com/en-us/library/hh848246.aspx .

The same example is available by handling the command wrapped into an event with the EventCommand class and then wrapped into an EventPattern message for reactive usage. Here's the code:

public MainWindow() 
{ 
    InitializeComponent(); 
    DataContext = this; 
 
    //command definition 
    var command = new EventCommand(); 
    ChangeValueCommand = command; 
 
    //sequence initialization 
 
    //register to the event from the command 
    Observable.FromEventPattern(command, "ExecuteRaised") 
    //subscribe to messages from the sequence 
    .Subscribe(eventDetail => 
    { 
        //EventArgs contains the Parameter of the command 
        Result += Convert.ToInt32(eventDetail.EventArgs); 
        //notify the value update 
        Notify("Result"); 
    }); 
} 

Here's the EventCommand class:

//a simplified CommandToEvent command 
public class EventCommand : ICommand 
{ 
    public event EventHandler<object> ExecuteRaised; 
    public event EventHandler CanExecuteChanged; 
 
    public bool CanExecute(object parameter) 
    { 
        return true; 
    } 
 
    public void Execute(object parameter) 
    { 
        if (ExecuteRaised != null) 
            ExecuteRaised(this, parameter); 
    } 
} 

The first difference that exists between the previous example and the one with ConsoleApplication in the preceding example is that, here, we injected into FromEventPattern a specific object (instance) that raises its event, while in the ConsoleApplication example, we specified a Type parameter because that event is static.

Other than this difference, the example is identical (in its design), because the WPF command-binding pattern is somehow already changing the event design into the Rx direction. What if we use a classic window/web form design? Here's an example:

//sequence initialization 
 
//register to buttons 
var button1Sequence = Observable.FromEventPattern(button1, "Click") 
//create the message to specify right numeric value 
.Select(x => -10); 
 
var button2Sequence = Observable.FromEventPattern(button2, "Click") 
//create the message to specify right numeric value 
.Select(x => -1); 
 
var button3Sequence = Observable.FromEventPattern(button3, "Click") 
//create the message to specify right numeric value 
.Select(x => +1); 
 
var button4Sequence = Observable.FromEventPattern(button4, "Click") 
//create the message to specify right numeric value 
.Select(x => +10); 
 
//create a single merged sequence 
button1Sequence.Merge(button2Sequence).Merge(button3Sequence).Merge(button4Sequence) 
//flatten values into a single 
.Scan((previous, actual) => previous + actual) 
//subscribe to handle value change 
.Subscribe(x => 
{ 
    //notify the value update 
    textBox1.Text = x.ToString(); 
}); 

The preceding example is within the constructor of a form. We have 4 buttons and TextBox for displaying the result. The example is identical to the WPF one, but here, we have a completely different Rx sequence. In Windows Forms, each button raises its Click event; this means that we need to create 4 sequences from the event pattern and merge these sequences into a single sequence. Once we have flattened the changing values, we need to find the result by using the Scan operator that gives us a rolling result. At the end of the sequence, a simple subscription sets the result to the textbox1.Text property.

FromEvent

The FromEvent method, similar to FromEventPattern, returns a sequence of the messages that represent event occurrences. The difference is that FromEvent gives us the ability to interact more deeply with the internals of the FromEvent sequence generation.

Instead of asking for a CLR event, as was the case with FromEventPattern, the FromEvent method asks for two actions. The first (registration) action gives us the internal Action<T> method that FromEvent uses to generate messages. The second (unregister) action give us again the same inner action to inform us to stop using that inner action to produce messages.

Here's a short example:

//the action from the FromEvent 
Action<string> fromEventAction = null; 
 
//setup the FromEvent sequence 
Observable.FromEvent<string>( 
    //register the inner action 
    innerAction => { fromEventAction = innerAction; },  
    //unregister the inner action 
    innerAction => { fromEventAction = null; } 
    ) 
    .Subscribe(x => Console.WriteLine("-> {0}", x)); 
 
while (true) 
{ 
    //invoke the inner action 
    fromEventAction(DateTime.Now.ToString()); 
    Thread.Sleep(1000); 
} 

This is one of the most powerful implementations within Rx between all the message generator operators available throughout the Observable class, because here, we have the ability to produce an arbitrary amount of messages simply with the delegate method available with Action<T>, a generic delegate.

Another way of using the FromEvent method is by using its inner actions to handle an external event. In a few words, we will receive a couple of delegates to ensure the registration/deregistration of our sequence. Then, we will append these delegates (as an event handler) to the external event we want to intercept to create messages. The message flow will start by intercepting the event.

Here's an example:

public static event Action MyStaticEvent; 
static void Main(string[] args) 
{ 
    //event sequence 
    var sequence = Observable.FromEvent( 
        //register the inner action as handler of the static event 
        x => MyStaticEvent += x,  
        //unregister the inner action from the static event 
        x => MyStaticEvent -= x); 
 
    //observer 
    sequence.Subscribe(unit => Console.WriteLine(unit)); 
 
    //manually raise the event 
    MyStaticEvent(); 
 
    Console.ReadLine(); 
} 

This usage of the FromEvent method is a bit useless because we could use the FromEventPattern instead. The difference is always that, with the FromEvent method we can register to the event (or to multiple events) by ourselves and later unregister in the same way.

ToEvent

The opposite of handling events as messages in the observable sequence is exposing a reactive message as events. This is a useful way of interacting with the existing (usually desktop) applications, because this choice makes available intercepting OnNext, OnCompleted, and OnError messages as events.

Here's a short example:

//an infinite sequence 
var sequence = Observable.Interval(TimeSpan.FromSeconds(1)).Select(x => DateTime.Now); 
 
//the event wrapper 
var eventWrapper = sequence.ToEvent(); 
 
//register the event handler 
eventWrapper.OnNext += x => Console.WriteLine("{0}", x); 
 
Console.ReadLine(); 
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.38.121