Skip to content

Instantly share code, notes, and snippets.

@kekekeks
Created April 25, 2015 09:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kekekeks/e0b0504dc8bac75697e7 to your computer and use it in GitHub Desktop.
Save kekekeks/e0b0504dc8bac75697e7 to your computer and use it in GitHub Desktop.
actorawait exceptions
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Diagnostics.Tracing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Akka.Actor;
using Akka.Actor.Internal;
using Akka.Dispatch;
using Akka.Dispatch.SysMsg;
using Newtonsoft.Json;
namespace Sandbox
{
public static class Program
{
public static void Main()
{
var system = ActorSystem.Create("test");
var actor = system.ActorOf(Props.Create<MyActor>());
actor.Tell("Hello");
actor.Tell("World");
actor.Tell("!");
system.AwaitTermination();
}
class MyActor : UntypedActor
{
protected override async void OnReceive(object message)
{
if (message is string)
{
try
{
await SomeTaskThatThrowsException().ActorAwait();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
else
{
Console.WriteLine("Unknown message: {0} - {1}", message.GetType(), message);
}
}
async Task SomeTaskThatThrowsException()
{
await Task.Delay(100);
throw new Exception("error");
}
}
//↓↓↓ MAGIC ↓↓↓
public static ActorAwaiter ActorAwait(this Task task)
{
return new ActorAwaiter(task);
}
public class ActorAwaiter : ICriticalNotifyCompletion, INotifyCompletion
{
private readonly Task _task;
private readonly AmbientState _state;
public ActorAwaiter(Task task)
{
_task = task;
var context = InternalCurrentActorCellKeeper.Current;
_state = new AmbientState
{
Sender = context.Sender,
Self = context.Self
};
}
public void GetResult()
{
_task.GetAwaiter().GetResult();
}
public ActorAwaiter GetAwaiter()
{
return this;
}
public bool IsCompleted{get { return _task.IsCompleted; }}
public void OnCompleted(Action continuation)
{
_task.ContinueWith(t =>
{
_state.Self.Tell(new CompleteTask(_state, continuation), _state.Sender);
}, TaskContinuationOptions.ExecuteSynchronously);
}
public void UnsafeOnCompleted(Action continuation)
{
OnCompleted(continuation);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment