Giter VIP home page Giter VIP logo

deferredevents's Introduction

Deferred Events

Project Maintenance License

CI Latest stable version

Twitter Follow

Deprecation notice

This repo has been deprecated as it is legacy and no longer maintained.

The DeferredEvents are now part of the Microsoft.Toolkit where it will be maintained from this point on.

This repository contains a .NET Standard 1.0 implementation for Deferred Events.

Deferred Events allows event invocators to await for the asynchronous completion of all event handlers.

Installation

Install the NuGet package by running the following command:

Install-Package DeferredEvents

Usage

Start by adding the namespace to your code files:

using DeferredEvents;

Change your events signature so that they can use DeferredEventArgs instead of EventArgs:

// before
public event EventHandler MyEvent;
// after
public event EventHandler<DeferredEventArgs> MyEvent;

If you have a custom event arguments class inheriting from EventArgs, just make it inherit from DeferredEventArgs instead.

Last step is to change the way you make your invocations:

// before
MyEvent?.Invoke(sender, EventArgs.Empty);
// after
await MyEvent.InvokeAsync(sender, new DeferredEventArgs());

The InvokeAsync() method is an extension method that will enable you to ensure we wait for the event handlers to finish their work before we proceed.

Last step will be to change the event handlers code so it can take advantage of the deferred execution:

// before
public void OnMyEvent(object sender, EventArgs e)
{
    // code
}
// after
public async void OnMyEvent(object sender, DeferredEventArgs e)
{
    var deferral = e.GetDeferral();
    
    // awaiteable code
    
    deferral.Complete();
}

You can also use the using pattern if you prefer:

// after
public async void OnMyEvent(object sender, DeferredEventArgs e)
{
    using (e.GetDeferral())
    {
        // awaiteable code
    }
}

You only need to call e.GetDeferral() if you actually want to the event caller to wait for the completion of the event handler; if you don't call it, it will just behave as a regular event handler.

You must call e.GetDeferral() to get an EventDeferral instance before any await call in your code to ensure that the event caller knows that it should wait for deferral.Complete(); ideally, it should be the first thing you do in the event handler code.

If you have indeed called e.GetDeferral(), then you must call deferral.Complete() to signal that the event handler has finished.

deferredevents's People

Contributors

pedrolamas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

mediabuff

deferredevents's Issues

Just a question: Does this lib really support multiple async listeners?

Please forgive me if this has been documented. I also haven't tried this library. Just looking at the code I found this:

        var tasks = eventHandler.GetInvocationList()
            .OfType<EventHandler<T>>()
            .Select(invocationDelegate =>
            {
                cancellationToken.ThrowIfCancellationRequested();

                invocationDelegate(sender, eventArgs);

                var deferral = eventArgs.GetCurrentDeferralAndReset();

                return deferral?.WaitForCompletion(cancellationToken) ?? CompletedTask;
            })
            .ToArray();

        return Task.WhenAll(tasks);

So InvokeAsync looks like it executes all the listeners. But in the DeferredEventArgs class I saw:

   public EventDeferral GetDeferral()
    {
        lock (_eventDeferralLock)
        {
            return _eventDeferral ?? (_eventDeferral = new EventDeferral());
        }
    }

In other words, a single instance of EventDeferral is used. That means if any of the listener task is complete, the entire InvokeAsync completes.

Right?

DeferredEventArgs.Empty cannot be used concurrently or in chained events

DeferredEventArgs.Empty is a static object and it potentially holds the same deferral object while completely independent async events are underway. This can lead to major interference - e.g., if one releases deferral another might no longer wait accordingly.

The fix to such scenarios, currently, is to disregard DeferredEventArgs.Empty and manually new the args object:

await MyEvent.InvokeAsync(sender, DeferredEventArgs.Empty);

The proper fix would be something like making DeferredEventArgs.Empty create a new object everytime it's used.

Repo Copy?

What happened

FYI, looks like there's another copy of the repo someone made without crediting your work: https://github.com/tibel/DeferredEvents

Also, as we discussed, we pulled this into the Toolkit repo would we want to maintain it there moving forward together as part of the new .NET Community Toolkit @Sergio0694 is going to help maintain?

I don't think you had unit tests at the time when we originally ported it over for UWP support, so those could be good to add on the Toolkit side as well.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.