我正在开发一个程序,该程序使用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循环完成我正在做的事情的最佳方法是什么?
答案 0 :(得分:2)
不要丢弃客户端并将其置于静态变量中。这样它就会继续运行并不断提高事件。根本不需要等待循环。删除using
语句。
如果这是你程序中的最后一个线程,你确实需要保持它。
Thread.Sleep(Timeout.Infinite);
答案 1 :(得分:1)
用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);
}
}
如果您不需要做任何事情来保持连接活动,除非阻止进程终止:
答案 2 :(得分:0)
避免线程阻塞的简单解决方案是在一段随机的时间内使用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);
}
}
}
如果执行需要在某个时刻停止,则可以使用while(true)
而不是CancellationToken
。 Task.Delay()
也支持这一点。
但这是控制台应用程序的所有解决方案。如果作为服务运行,服务主机将确保您的程序在启动后继续执行,因此您可以返回。