Project Description

This is a .NET library that allows you to stop running the code wherever you want in order to await an event using the functionality of yield sentence. It's useful when you want to await asynchronous events or when you have to deal with many events in a sequential way.


Table of Contents

  • What is This Like?
  • How to Start to Use Most Easily
  • One of Useful Examples
  • Documentation Outline


What is This Like?

When you use this library, the code would be like the following style.

using SimonPG.WaitCore; // [A]

public partial class Form1 : Form {

    IEnumerable<bool> TestFunc(EventWaiter waiter) { // [B]

        // ...Process A...

        yield return waiter.Wait(button1, "Click"); // [C]

        // ...Process B...
    }

    void Form1_Load(object sender, EventArgs e) {
        new EventWaiter(TestFunc); // [D]
    }
}

The points are:

  1. [A] : Importing the namespace "SimonPG.WaitCore", which contains this library.
  2. [B] : Defining an yield function in the form of IEnumerable<bool> FuncName(EventWaiter waiter), with getting EventWaiter and returning IEnumerable.
  3. [C] : Writing yield return in the line where you want to await an event.
  4. [D] : Initial call of the function defined in [B].

The flow of this code when it runs

  1. A Form1.Load event occurs,
  2. The line [D] runs,
  3. The function [B] is called,
  4. The line "...Process A..." runs,
  5. The line [C] runs and the function ends here because of yield return,
  6. Windows message loop runs,
  7. Someone clicks the button "button1" for example,
  8. A button1.Click event occurs,
  9. The function [B] is called again and the code just after the line [C] runs,
  10. The line "...Process B..." runs,
  11. The function [B] ends.

What does it mean?

It means that in the function [B] you can await the Click event just in the line [C] until the event occurs. It looks as if the code was stopped in the line [C] until the event occurs and run again just after the line [C] when the event occurs.

Please read the next section titled "How to Start to Use Most Easily" for the details.


How to Start to Use Most Easily

00081.JPG
  1. Download the library and get the file "WaitCore.cs".
  2. Create your solution in Visual C# 2008 IDE or later. (it works in Express Edition as well)
  3. Create your project of Windows Form Application.
  4. Include the file "WaitCore.cs" to your project.
  5. Create a Form.Load event by double-clicking the default form Form1.
  6. Create a button named as button1 on the form.
  7. Make the code like the following:
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using SimonPG.WaitCore; // [A]

namespace WindowsFormsApplication1 {

    public partial class Form1 : Form {

        public Form1() {
            InitializeComponent();
        }

        IEnumerable<bool> TestFunc(EventWaiter waiter) { // [B]

            Console.WriteLine("...Process A..."); // ...Process A...

            yield return waiter.Wait(button1, "Click"); // [C]

            Console.WriteLine("...Process B..."); // ...Process B...
        }

        void Form1_Load(object sender, EventArgs e) {
            new EventWaiter(TestFunc); // [D]
        }
    }
}

The result

  1. When you build and run the code, you will see "...Process A..." output in the IDE console first.
  2. If you click the button1, then you will see "...Process B..." output in the IDE console.
The behavior of the result means that in the function [B] you can await the Click event just in the line [C] until the event occurs. It looks as if the code was stopped in the line [C] until the event occurs and run again just after the line [C] when the event occurs.
00083.JPG

Download

This example project including all the source code is available for download:

One of Useful Examples

Blinking Example

Here is a sample code which blinks the label1 UI in the way like black -> gray -> white -> gray -> black... The great point is that you can implement such a feature without using any field variables and without using any lambda functions. You can implement with just a normal code including one while loop and two for loops only.

using SimonPG.WaitCore;

public partial class Form1 : Form {

    IEnumerable<bool> TestFunc(EventWaiter waiter) {

        while (true) {

            for (var bright = 0; bright < 255; bright += 10) {
                label1.BackColor = Color.FromArgb(bright, bright, bright);
                yield return waiter.Wait(timer1, "Tick");
            }

            for (var bright = 255; bright > 0; bright -= 10) {
                label1.BackColor = Color.FromArgb(bright, bright, bright);
                yield return waiter.Wait(timer1, "Tick");
            }
        }
    }

    void Form1_Load(object sender, EventArgs e) {
        new EventWaiter(TestFunc);
    }
}

If you want to know more, please see the documentation page (Useful Examples).


Documentation Outline

Examples

  1. Useful Example 1 (blinking a label background by awaiting timer.Tick events)
  2. Comparing Code Styles of Normal Code, Rx and YieldAwait

Stories

  1. Where Did This Idea Come from?

Others

  1. All Links

Last edited Jun 6, 2012 at 9:44 AM by simon_p_g_soft, version 45