2016-04-16 81 views
2

Windowsサービスを使用して定期的にテレグラムメッセージを送信します(2分ごと)。私のWindowsサービスは正常に起動し、2分後に停止します。私は自分のコードをチェックし、それが非同期であることを知る。どうすれば問題を解決できますか?ElapsedEventHandler内から非同期メソッドを呼び出す方法

protected override void OnStart(string[] args) 
{ 
    //< I declared a System.Timers.Timer to send new Telegram messages. 
    aTimer = new System.Timers.Timer(120000); // 2 minutes 
    aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent); 
    aTimer.Enabled = true; 

    GC.KeepAlive(aTimer); 
    //> 
} 

private static void OnTimedEvent(object source, ElapsedEventArgs e) 
{ 
    SendNewMessages(); 
} 

async static void SendNewMessages() 
{ 
    MyDataContext myDB = new MyDataContext(); 
    var newMessages = myDB.TelegramMessages.Where(tm => tm.Status != "New Message"); 

    foreach (TelegramMessage newMessage in newMessages) 
    { 
     try 
     { 
      var store = new FileSessionStore(); 
      var client = new TelegramClient(store, "MySession"); 
      await client.Connect(); 

      var res = await client.ImportContactByPhoneNumber(newMessage.ReceiverPhoneNumber); 
      await client.SendMessage(res.Value, newMessage.Message); 

      newMessage.Status = "Sent"; 
      myDB.SubmitChanges(); 
     } 
     catch (Exception ex) 
     { 
      newMessage.Status = ex.Message; 
      myDB.SubmitChanges(); 
     } 

     Thread.Sleep(5000); 
    } 
} 
+0

を終わるだろうそれ。これを最小限の再現可能な例に減らすことをお勧めします。実際の問題は他にもあると思います。たとえば、未処理の例外です。 –

答えて

1

一つ、私が直接見る事が非同期で/待つということですが、「SendNewMessagesは」voidを返すので、イベントハンドラにすべての方法を実装されていません。イベントハンドラは非同期ではありません。

According to MSDN on "Async Return Types (C# and Visual Basic)"

空隙戻り型(Visual BasicのSubプロシージャ)の主な用途は、ボイドの戻り型が必要とされるイベントハンドラです。ボイドを返すメソッドをオーバーライドするために、または「ファイアアンドファー」と分類できるアクティビティを実行するメソッドのために、ボイドリターンを使用することもできます。

あなたはそれがこの

private async static void OnTimedEvent(object source, ElapsedEventArgs e) 
{ 
    await SendNewMessages(); 
} 

UPDATED

にこの

async static Task SendNewMessages() 

そして、あなたのEventHandlerにごSendNewMessageを変更してみてくださいことができるようにこれは、最も可能性の高いシナリオでは問題ですあなたの "SendNewMessages"メソッドにエラー処理コードを追加するのも良い考えです。なぜなら、例外がスローされると、あなたのサービスは終了します。現時点で

async static Task SendNewMessages() 
{ 
    try 
    { 
    ... Your code here 
    } 
    catch(Exception e) 
    { 
    ... exceptionhandling here 
    } 
} 

あなたは、あなたのforeach内exceptionhandlingてきていますが、データベース・コードのために(私の知る限り)任意のerrorhandlingを持っていません。

例外はここ

MyDataContext myDB = new MyDataContext(); 
var newMessages = myDB.TelegramMessages.Where(tm => tm.Status != "New Message"); 

foreach (TelegramMessage newMessage in newMessages) 

またはこちらを投げるの場合:

newMessage.Status = ex.Message; 
myDB.SubmitChanges(); 

サービスは、私は自分のコードをチェックして、私は疑うasync`のため、それが見つける `

+0

あなたの言ったように私のコードを変更しましたが、SendNewMessages()を呼び出した後にWindowsサービスが停止しました。 – Mohsen

+0

私はいくつかの返事を待っています。どんな答えも高く評価されます。 – Mohsen

+1

@MohsenJafariさらに調査したら答えを更新します – Shazi