Skip to content

Instantly share code, notes, and snippets.

@temurka1
Created September 1, 2018 03:45
Show Gist options
  • Select an option

  • Save temurka1/f76cb46488a2aee5e2ad8bf897f5ebc5 to your computer and use it in GitHub Desktop.

Select an option

Save temurka1/f76cb46488a2aee5e2ad8bf897f5ebc5 to your computer and use it in GitHub Desktop.

Revisions

  1. temurka1 created this gist Sep 1, 2018.
    51 changes: 51 additions & 0 deletions eventawaiter.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,51 @@
    namespace Proto.Events
    {
    using System;
    using System.Collections.Concurrent;
    using System.Runtime.CompilerServices;
    using System.Threading;

    public sealed class EventAwaiter<TEventArgs> : INotifyCompletion
    {
    #region Fields

    private readonly ConcurrentQueue<TEventArgs> _events = new ConcurrentQueue<TEventArgs>();
    private Action _continuation;

    #endregion

    #region Properties

    public bool IsCompleted => _events.Count > 0;

    #endregion

    #region Methods

    public EventAwaiter<TEventArgs> GetAwaiter()
    {
    return this;
    }

    public void OnCompleted(Action continuation)
    {
    Volatile.Write(ref _continuation, continuation);
    }

    public TEventArgs GetResult()
    {
    _events.TryDequeue(out TEventArgs result);
    return result;
    }

    public void EventRaised(object sender, TEventArgs args)
    {
    _events.Enqueue(args);

    Action continuation = Interlocked.Exchange(ref _continuation, null);
    continuation?.Invoke();
    }

    #endregion
    }
    }
    49 changes: 49 additions & 0 deletions program.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,49 @@
    namespace Proto
    {
    using Proto.Events;
    using System;
    using System.Runtime.ExceptionServices;

    public static class Program
    {
    public static void Main(string[] args)
    {
    ShowExceptions();

    for (int i = 0; i < 3; i++)
    {
    try
    {
    switch (i)
    {
    case 0:
    throw new InvalidOperationException();

    case 1:
    throw new ObjectDisposedException("");

    case 2:
    throw new ArgumentOutOfRangeException();
    }
    }
    catch
    {

    }
    }

    Console.ReadKey();
    }

    private static async void ShowExceptions()
    {
    var eventAwaiter = new EventAwaiter<FirstChanceExceptionEventArgs>();
    AppDomain.CurrentDomain.FirstChanceException += eventAwaiter.EventRaised;

    while (true)
    {
    Console.WriteLine("AppDomain exception {0}", (await eventAwaiter).Exception.GetType());
    }
    }
    }
    }