[英]How to keep an asynchronous program running?
我正在使用S22 imap保持與gmail的IDLE連接並實時接收消息的程序。
我正在從Main方法調用以下函數:
static void RunIdle()
{
using (ImapClient Client = new ImapClient("imap.gmail.com", 993, "user", "pass", AuthMethod.Login, true))
{
if (!Client.Supports("IDLE"))
throw new Exception("This server does not support IMAP IDLE");
Client.DefaultMailbox = "label";
Client.NewMessage += new EventHandler<IdleMessageEventArgs>(OnNewMessage);
Console.WriteLine("Connected to gmail");
while (true)
{
//keep the program running until terminated
}
}
}
使用無限的while循環可以工作,但是似乎會有更正確的方法來做到這一點。 將來,如果我想添加更多的IDLE連接,則看到我的解決方案有效的唯一方法是為每個連接使用單獨的線程。
完成while循環的最佳方法是什么?
不要丟棄客戶端並將其植根於靜態變量中。 這樣,它就保持運行並不斷引發事件。 根本不需要等待循環。 刪除using
語句。
如果這是程序中的最后一個線程,則確實需要保持其活動狀態。
Thread.Sleep(Timeout.Infinite);
完成while循環的最佳方法是什么?
您可能需要做以下兩件事:
RunIdle
與CancelationToken
,以便它可以干凈地停止。 在忙於等待的while
循環中,使用Task.Delay
進行“睡眠”,直到需要再次“ ping”郵箱為止。
static async Task RunIdle(CancelationToken cancelToken, TimeSpan pingInterval) { // ... // the new busy waiting ping loop while (!cancelToken.IsCancellationRequested) { // Do your stuff to keep the connection alive. // Wait a while, while freeing up the thread. if (!cancelToken.IsCancellationRequested) await Task.Delay(pingInterval, cancelToken); } }
如果您不需要執行任何操作來保持連接活動,除了可以防止進程終止:
一個避免線程阻塞的簡單解決方案是只使用Task.Delay()
一段隨機的時間。
static async Task RunIdle(CancellationToken token = default(CancellationToken))
{
using (ImapClient Client = new ImapClient("imap.gmail.com", 993, "user", "pass", AuthMethod.Login, true))
{
...
var interval = TimeSpan.FromHours(1);
while (!token.IsCancellationRequested)
{
await Task.Delay(interval, token);
}
}
}
可以使用CancellationToken
代替while(true)
,以防執行需要在某個時刻停止。 Task.Delay()
支持此功能。
不過,這些都是控制台應用程序的所有解決方案。 如果作為服務運行,則服務主機將確保您的程序在啟動后繼續執行,因此您可以返回。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.