2016-04-16 3 views
2

Я собираюсь использовать службу Windows для периодической отправки сообщений Telegram (каждые две минуты). Моя служба Windows начнет нормально работать, и через 2 минуты она остановится. Я проверил свой код и выяснил, что это из-за асинхронности. Как я могу решить проблему?Как вызвать метод Async изнутри 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

'Я проверил мой код и выяснить, что это из-за async' я сомневаюсь Это. Я рекомендую уменьшить это до минимального воспроизводимого примера, и я подозреваю, что вы обнаружите, что фактическая проблема - это что-то другое. Например, необработанное исключение. –

ответ

1

Одна вещь, которую я вижу в том, что непосредственно асинхронной/ОЖИДАНИЕ не был реализован весь путь к EventHandler, так как «SendNewMessages» возвращает ничтожным. И ваш обработчик событий не является асинхронным.

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

Основное использование возвращаемого типа недействительным (Sub процедуры в Visual Basic), в обработчиках событий, где требуется тип возврата недействительным. Возвращение void также может использоваться для переопределения методов возврата void или для методов, которые выполняют действия, которые можно классифицировать как «огонь и забыть».

Это, скорее всего, проблема в вашем сценарии, так что вы можете попробовать изменить свой SendNewMessage к этому

async static Task SendNewMessages() 

И ваш EventHandler к этому

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

Обновлено

Это также было бы хорошей идеей добавить некоторый код обработки ошибок в ваш метод SendNewMessages, поскольку, если выдается исключение, ваше обслуживание прекратится.

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

На данный момент у вас есть только 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(); 

Служба закончится

+0

Я поменял свой код, как вы сказали, но служба Windows остановлена ​​после вызова waitNewMessages(); – Mohsen

+0

Я жду ответа. Любой ответ будет оценен. – Mohsen

+1

@MohsenJafari Я буду обновлять ответ после того, как я еще раз исследовал – Shazi

Смежные вопросы