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.
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
}
}
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());
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment