C# 如何保持异步程序运行?
我正在开发一个程序,它使用S22 imap保持与gmail的空闲连接并实时接收消息 我正在从主方法调用以下函数:C# 如何保持异步程序运行?,c#,asynchronous,C#,Asynchronous,我正在开发一个程序,它使用S22 imap保持与gmail的空闲连接并实时接收消息 我正在从主方法调用以下函数: static void RunIdle() { using (ImapClient Client = new ImapClient("imap.gmail.com", 993, "user", "pass", AuthMethod.Login, true)) { if (!Client.Supports("IDLE")) th
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循环是可行的,但似乎有一种更正确的方法可以做到这一点。在将来,如果我想添加更多空闲连接,我认为解决方案工作的唯一方式是为每个连接使用单独的线程
完成while循环的最佳方法是什么 避免线程阻塞的一个简单解决方案是只使用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来代替whiletrue,以防执行需要在某个点停止。任务。延迟也支持这一点
不过,这些都是控制台应用程序的解决方案。如果作为服务运行,服务主机将确保您的程序在启动后继续执行,因此您可以返回。避免线程阻塞的一个简单解决方案是只使用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来代替whiletrue,以防执行需要在某个点停止。任务。延迟也支持这一点
不过,这些都是控制台应用程序的解决方案。如果作为服务运行,服务主机将确保您的程序在启动后继续执行,这样您就可以返回
完成while循环的最佳方法是什么
您可能需要做以下两件事:
为RunIdle提供一个CancelationToken,以便可以完全停止它。
在忙等待时循环中,使用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);
}
}
如果您不需要执行任何操作来保持连接处于活动状态,除了防止进程终止之外:
从控制台读取并等待,直到出现ctrl+c或一些干净的退出命令。
完成while循环的最佳方法是什么
您可能需要做以下两件事:
为RunIdle提供一个CancelationToken,以便可以完全停止它。
在忙等待时循环中,使用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);
}
}
如果您不需要执行任何操作来保持连接处于活动状态,除了防止进程终止之外:
从控制台读取并等待,直到出现ctrl+c或一些干净的退出命令。
不要丢弃客户端并将其根放到静态变量中。这样,它就可以继续运行并不断引发事件。根本不需要等待循环。删除using语句 如果这是程序中的最后一个线程,那么您确实需要让它保持活动状态
Thread.Sleep(Timeout.Infinite);
不要丢弃客户端并将其根放到静态变量中。这样,它就可以继续运行并不断引发事件。根本不需要等待循环。删除using语句 如果这是程序中的最后一个线程,那么您确实需要让它保持活动状态
Thread.Sleep(Timeout.Infinite);
为什么你的方法被声明为异步的,你在它的任何地方都不使用wait。我正在尝试其他可能的解决方案。为了清楚起见,删除了。这是什么样的程序?控制台应用程序?Winforms?WPF?@JamesThorpe目前它是一个控制台程序,但最终将成为一个服务。如果它是一个服务,你将不需要这样的东西-该服务有自己的消息泵,并且不会停止运行。只要像平常一样创建和使用对象,事件就会触发,不需要让线程挂起等待。为什么你的方法声明为异步,你在其中的任何地方都不使用wait。我正在尝试其他可能的解决方案。为了清楚起见,删除了。这是什么样的程序?控制台应用程序?Winforms?WPF?@JamesThorpe目前它是一个控制台程序,但最终将成为一个服务。如果它是一个服务,你将不需要这样的东西-该服务有自己的消息泵,并且不会停止运行。只要像平常一样创建和使用对象,事件就会触发,没有必要让线程挂起等待。