[英]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.