One time generic event call?

javascript custom events
javascript events
javascript custom events w3schools
dispatchevent jquery
dispatchevent click
react dispatch event
javascript custom events on objects
python sched tutorial

What I am trying to achieve is to create convenient syntax for calling a callback on an event only once.

public static class Extensions
{
    public static void Once<T>(this EventHandler<T> @event, EventHandler<T> callback)
    {
        EventHandler<T> cb = null;
        cb = (object that, T info) => {
            if (callback != null) {
                callback(that, info);
            }
            @event -= cb;
        };
        @event += cb;
    }
}

This should allow us to write something like this:

obj.OnSomething.Once((sender, obj) => Console.WriteLine(obj));

Note that OnSomething is an event EventHandler of some type.

The problem is that I get the error message:

Error CS0070: The event SharpTox.Core.Tox.OnFriendMessage' can only appear on the left hand side of += or -= when used outside of the type SharpTox.Core.Tox' (CS0070) (SharpTox.Tests)

Is there no way to achieve this that easily? Do I have to remove event from OnSomething and make it a simple delegate?

Unfortunately, you can't have a nice syntax here. Like the error message says, all you can do with an event field from outside of its defining class is referencing it at the left of += or -=.

Here's the method that Rx uses to bind an observable to an event:

var observable = Observable.FromEventPattern(
    handler => obj.OnSomething += handler,
    handler => obj.OnSomething -= handler);

Basically, FromEventPattern is a helper that takes two lambdas: one for subscription, and the other for unsubscription. You could use a similar pattern, or just use Rx to achieve the same effect:

Observable.FromEventPattern(h => obj.OnSomething += h, h => obj.OnSomething -= h)
          .Take(1)
          .Subscribe(e => ...);

On a side note, this will keep a reference to obj from the lambda used in Subscribe (there are intermediary glue objects but this is irrelevant). This means that if the event is never called, and if the lambda is long-lived, then obj won't be eligible for GC (a situation called event memory leak). This may or may not be a problem for your case.

Speaking of Events, Kim makes use of moments of time. Of course, Chisholm can call certain properties generic events, but the real events in his theory, one would like to say, are  Now that you know what events and event listeners are, let’s see what one time event listeners are. One time event listeners Event listeners are great, addEventListener() is used everywhere.

An alternative approach would be to return the callback. In the extension method the callback is deleted/removed. The drawback of this approach is still the fact that the event handler function needs to be defined separately and can not be a lambda.

The extension method:

public static class Extensions
{   
    public static EventHandler<T> Once<T>(this Action<Object, T> callback)
    {
        return (Object s, T e) => 
        {
            if (callback != null) {
                callback(s, e);
                callback = null;
            }
        };
    }
}

A demo class that has different events:

public class Demo
{
    public event EventHandler<String> StringEvent = null;
    public event EventHandler<Int32> IntEvent = null;

    public void NotifyOnWork()
    {
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine(i);
            if (this.StringEvent != null) { this.StringEvent(this, i.ToString()); }
            if (this.IntEvent != null) { this.IntEvent(this, i); }
        }
    }
}

Usage of the Demo class:

var demo = new Demo();
Action<Object, String> handlerString = (s, e) =>  { Console.WriteLine("echo string {0}", e); };
Action<Object, Int32> handlerInt = (s, e) =>  { Console.WriteLine("echo int {0}", e); };

demo.StringEvent += handlerString.Once();
demo.IntEvent += handlerInt.Once();
demo.StringEvent += (s, e) => Console.WriteLine("i = {0}", e); 
demo.NotifyOnWork();

And the output is:

0
echo string 0
i = 0
echo int 0
1
i = 1
2
i = 2
3
i = 3
4
i = 4

The Effectiveness of Causes, The causal statement about a particular event is being made about it as an An event is a concrete object or a n-tuple of objects exemplifying a property at a time. also be constitutive of what Kim calls 'generic events', for example a drinking  Start Multiple Async Tasks and Process Them As They Complete (C#) 09/12/2018; 5 minutes to read +9; In this article. By using Task.WhenAny, you can start multiple tasks at the same time and process them one by one as they’re completed rather than process them in the order in which they're started.

You've posted an answer to a similar problem here.

The syntax would look somewhat like this:

obj.Event += (s, e) =>
{
    Detach(s, nameof(obj.Event));
    // ..do stuff..
};

The Detach method would look like this and can be put anywhere you like (most likely a static helper class):

public static void Detach(object obj, string eventName)
{
    var caller = new StackTrace().GetFrame(1).GetMethod();
    var type = obj.GetType();
    foreach (var field in type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic))
    {
        if (typeof(Delegate).IsAssignableFrom(field.FieldType))
        {
            var handler = (field.GetValue(obj) as Delegate)?.GetInvocationList().FirstOrDefault(m => m.Method.Equals(caller));
            if (handler != null)
            {
                type.GetEvent(eventName).RemoveEventHandler(obj, handler);
                return;
            }
        }
    }
}

Dispatching custom events, Build-in event classes form a hierarchy, similar to DOM element classes. The root is the built-in Event After an event object is created, we should “run” it on an element using the call elem. Please note: the generic Event constructor does not allow that. Let's try: That's a bad architecture most of the time. Presuming your handler event argument is named ‘e’, the line: e.target.removeEventListener(e.type, arguments.callee); will remove the handler the first time it’s invoked. It doesn’t matter

sched – Generic event scheduler., The sched module implements a generic event scheduler for running tasks at specific times. Events can be scheduled to run after a delay, or at a specific time. A number representing the delay; A priority value; The function to call; A tuple  But the value of the variable itself might change between the time one compares it to null, and the time one accesses it again to invoke the delegate instance. The variable in question here is the field named “Foo” (to code outside the declaring class, this member is an “event”, but inside the class it’s essentially just a field).

Generic Events, Summer officially kicks off at Santa Monica Pier 360. Participate in a variety of beach sports or just enjoy the live music, Beer & Spirits Garden, and entertainment  The jQuery example is an event handler, and once the event handler has been called it is removed from the element. The equivalent in C# for (eg.) an button click event would be myButton.Click += new EventHandler(MyEventHandler) void MyEventHandler(object sender, EventArgs e) { Console.Write("hello"); ((Button)sender).Click -= new EventHandler

About Generic Events, In order to put an event on we have to build a team which we call Race Day We are looking for hard workers that aren't afraid of a 4:00 a.m. start time and  As mentioned above, event handlers that take arguments - such as MouseDown (Button As Integer, Shift As Integer, X As Single, Y As Single) - aren't compatible without losing the data that would be passed to the parameters. The TextBox0_GotFocus () -type handlers must be altered to Public rather than Private - CallByName can't find Private handlers.

Comments
  • "Unfortunately, you can't have a nice syntax here." This is due to C#'s language specification. Here is the petition to fix that NB. F# Can do this nicely.
  • The downside is that you never unsubscribe from the events, so the event handlers stay forever and degrade the performance over time.
  • Yes, it degrades performance, but I need this only to write nice looking test cases, so the syntax is clearer and the performance impact is neglectible.