简体   繁体   English

如何保持异步程序运行?

[英]How to keep an asynchronous program running?

I'm working on a program that uses S22 imap to keep an IDLE connection to gmail and receive messages real time. 我正在使用S22 imap保持与gmail的IDLE连接并实时接收消息的程序。

I am calling the following function from my Main method: 我正在从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
        }

    }
}

Using the infinite while loop works, but it seems there would be a more correct way to do this. 使用无限的while循环可以工作,但是似乎会有更正确的方法来做到这一点。 In the future if I want to add more IDLE connections, the only way I see my solution working is with a separate thread for each connection. 将来,如果我想添加更多的IDLE连接,则看到我的解决方案有效的唯一方法是为每个连接使用单独的线程。

What is the best way to accomplish what I am doing with the while loop? 完成while循环的最佳方法是什么?

Do not dispose of the client and root it in a static variable. 不要丢弃客户端并将其植根于静态变量中。 That way it just stays running and keeps raising events. 这样,它就保持运行并不断引发事件。 There is no need to have a waiting loop at all. 根本不需要等待循环。 Remove the using statement. 删除using语句。

If this is the last thread in your program you indeed need to keep it alive. 如果这是程序中的最后一个线程,则确实需要保持其活动状态。

Thread.Sleep(Timeout.Infinite);

What is the best way to accomplish what I am doing with the while loop? 完成while循环的最佳方法是什么?

You may want to do the following two things: 您可能需要做以下两件事:

  1. Provide your RunIdle with a CancelationToken so that it can be cleanly stopped. 提供您的RunIdleCancelationToken ,以便它可以干净地停止。
  2. In your busy waiting while loop, use Task.Delay to "sleep" until you need to "ping" the mailbox again. 在忙于等待的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); } } 
  3. If you don't need to do anything to keep the connection alive, except from keeping the process from terminating: 如果您不需要执行任何操作来保持连接活动,除了可以防止进程终止:

    • Read from the console and wait until there is a ctrl + c or some clean "exit" command. 从控制台读取并等待直到有ctrl + c或一些干净的“退出”命令。

A simple solution that avoid thread blocking would be to just use Task.Delay() for some random amount of time. 一个避免线程阻塞的简单解决方案是只使用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);
        }
    }
}

Instead of while(true) you could perhaps use a CancellationToken in case the execution needs to be stop at some point. 可以使用CancellationToken代替while(true) ,以防执行需要在某个时刻停止。 Task.Delay() supports this as well. Task.Delay()支持此功能。

This are all solutions for a Console application, though. 不过,这些都是控制台应用程序的所有解决方案。 If running as a service, the service host will make sure your program keeps executing after starting, so you can just return. 如果作为服务运行,则服务主机将确保您的程序在启动后继续执行,因此您可以返回。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 关闭程序后如何保持进程运行? - How to keep process running after closing the program? 如何跟踪长时间运行的并行程序的运行位置 - how to keep track of running location for a long running parallel program 异步程序未异步运行的奇怪行为 - Strange behavior with asynchronous program not running asynchronously 如何在C#程序退出时保持批处理文件运行? - How to keep batch file running while C# program quit? C#:在运行程序并使用 if 语句回答输入后,如何让程序继续提问? - C#: After running program and the input is answered with an if statement, how do i get the program to keep asking the question? 试图使代码异步但没有阻塞我的程序快要消失了吗? - Trying to make code asynchronous but without blocking my program is running away? 如何保持得分? - How to keep a running score? 如何对异步Windows窗体应用程序进行编程? - How to program asynchronous Windows Forms Applications? 当失去焦点时如何使C#命令行程序保持运行 - How to keep the C# command line program still running when it loses focus 无论客户端发生什么情况,我如何让服务器程序继续运行? - How can I make a server program keep running no matter what happens to a client?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM