Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何保持异步程序运行?_C#_Asynchronous - Fatal编程技术网

C# 如何保持异步程序运行?

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

我正在开发一个程序,它使用S22 imap保持与gmail的空闲连接并实时接收消息

我正在从主方法调用以下函数:

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目前它是一个控制台程序,但最终将成为一个服务。如果它是一个服务,你将不需要这样的东西-该服务有自己的消息泵,并且不会停止运行。只要像平常一样创建和使用对象,事件就会触发,没有必要让线程挂起等待。