Azure ServiceFabric - ActorのTimerやAlarmを自動で起動

Actorはいずれかの処理が呼ばれた場合にActiveになる。
そのため、初回起動時は何かしらの処理を実行しない限りTimerやAlarmも起動しない。

ActorServiceクラスを拡張することで、初回起動時にTimerやAlarmを起動させることができる。

### ActorのOnActivyAsyncメソッド内にTimerやAlarmの起動処理を追加する

OnActive内でTimerやAlarmを起動する。(下記の例はAlarm)
(2017/08/30追記　現状原因不明だがアップデート時に前回起動のreminderが終了していない場合があるため残っていたら終了させる)

```C#:HogeActorService.cs
protected override async Task OnActivateAsync()
{
    ActorEventSource.Current.ActorMessage(this, "Actor activated.");
    try
    {
        var registerReminder = GetReminder(RequestLimitDataActorName);
        await UnregisterReminderAsync(registerReminder);
    }
    catch (ReminderNotFoundException) 
    { // 処理なし }
    var reminder = await this.RegisterReminderAsync(
                  "Hoge Actor",
                  null,
                  TimeSpan.FromMilliseconds(0),
                  TimeSpan.FromMinutes(10)
                );
}
```

### ActorServiceを拡張したクラスを作成
ActorServiceを拡張し、RunAsyncメソッド内で起動時に呼び出すActorのメソッドをコール

```C#:HogeActorService.cs
    public class HogeActorService : ActorService
    {
        public HogeActorService (StatefulServiceContext context, 
                                                         ActorTypeInformation actorTypeInfo, 
                                                         Func<ActorService, ActorId, ActorBase> actorFactory = null,
                                                         Func<ActorBase, IActorStateProvider, IActorStateManager> stateManagerFactory = null,
                                                         IActorStateProvider stateProvider = null, 
                                                         ActorServiceSettings settings = null) 
            : base(context, actorTypeInfo, actorFactory, stateManagerFactory, stateProvider, settings)
        { }


	        protected async override Task RunAsync(CancellationToken cancellationToken)
	        {
	            await base.RunAsync(cancellationToken);
	            var proxy = ActorProxy.Create<IHogeActor>(new ActorId(0));
                    // 起動時にに呼び出すActorのメソッドをコール
	            await proxy.HogeHoge();
	        }
    }
```

### 独自のActorServieを利用するように変更
Mainメソッド内で利用しているActorServiceを独自のものに変更
変更前

```C#
private static void Main()
{
    try
    {
        ActorRuntime.RegisterActorAsync<HogeActor>(
                   (context, actorType) => new ActorService(context, actorType)).GetAwaiter().GetResult();

        Thread.Sleep(Timeout.Infinite);
    }
    catch (Exception e)
    {
        ActorEventSource.Current.ActorHostInitializationFailed(e.ToString());
        throw;
    }
}
```

変更後 (2017/05/30 起動時にエラーとなるため修正)

```C#
private static void Main()
{
    try
    {
        ActorRuntime.RegisterActorAsync<HogeActor>(
                   (context, actorType) => new HogeActorService(context, actorType, (service, id) => new HogeActor(service, id))).GetAwaiter().GetResult();

        Thread.Sleep(Timeout.Infinite);
    }
    catch (Exception e)
    {
        ActorEventSource.Current.ActorHostInitializationFailed(e.ToString());
        throw;
    }
```

(2017/06/17追記) Alarmの終了処理を記述(終了処理の記述がないと、更新のデプロイ時に失敗するので必ず終了処理を記述)

```C#
        protected override async Task OnDeactivateAsync()
        {
            var register = GetReminder("Hoge Actor");
            await UnregisterReminderAsync(register);

            await base.OnDeactivateAsync();
        }
````