Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.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# 是否可以使用System.Threading.Timer运行异步任务?_C#_.net - Fatal编程技术网

C# 是否可以使用System.Threading.Timer运行异步任务?

C# 是否可以使用System.Threading.Timer运行异步任务?,c#,.net,C#,.net,所以我使用线程计时器,希望每10秒运行一次任务。在这个异步任务方法中,我在其中运行其他任务。我试着用System.Threading.Timer来做这件事 _taskTimer = new Timer(statusChecker.CheckStatus, autoEvent, 1000, 250); 似乎你不能等待你分配给它的功能。这有什么办法吗?我已经用谷歌搜索了好几次这个问题,但是所有的问题都无关紧要,所以我会发布一些关于非同步解决方案的帖子。对于这个用例,你并不需要计时器。以下是在控制台

所以我使用线程计时器,希望每10秒运行一次任务。在这个异步任务方法中,我在其中运行其他任务。我试着用System.Threading.Timer来做这件事

_taskTimer = new Timer(statusChecker.CheckStatus, autoEvent, 1000, 250);

似乎你不能等待你分配给它的功能。这有什么办法吗?我已经用谷歌搜索了好几次这个问题,但是所有的问题都无关紧要,所以我会发布一些关于非同步解决方案的帖子。

对于这个用例,你并不需要计时器。以下是在控制台程序中每x秒连续调用函数的一种方法:

class Program
{
    static Task statusCheckingTask;
    static void Main(string[] args)
    {
        statusCheckingTask = CheckStatusTask(10);
        Console.ReadLine();
    }

    static async Task CheckStatusTask(int delayInSeconds)
    {
        while (true)
        {
            await CheckStatus();
            await Task.Delay(TimeSpan.FromSeconds(delayInSeconds));
        }
    }

    static async Task CheckStatus()
    {
        Console.WriteLine("Checking status...");
        await Task.FromResult(0);
    }

}

如果您希望每250毫秒进行一次状态检查,而不管以前的尝试结果如何,请使用以下命令:

while (true)
{
    Task.Run(() => statusChecker.CheckStatus(autoEvent));

    await Task.Delay(TimeSpan.FromSeconds(250));
}
while (true)
{
    await statusChecker.CheckStatus(autoEvent);

    await Task.Delay(TimeSpan.FromSeconds(250));
}

如果要仅在上一次尝试完成时启动状态检查,请使用以下命令:

while (true)
{
    Task.Run(() => statusChecker.CheckStatus(autoEvent));

    await Task.Delay(TimeSpan.FromSeconds(250));
}
while (true)
{
    await statusChecker.CheckStatus(autoEvent);

    await Task.Delay(TimeSpan.FromSeconds(250));
}
这两种情况都假设statusChecker.CheckStatus返回一个任务对象,例如:

public async Task CheckStatus(object autoEvent)
{
    // some async status checking
}

我建议使用微软的反应式框架NuGet System.Reactive和add using System.Reactive.Linq;然后你可以这样做:

IObservable<bool> query =
    from n in Observable.Interval(TimeSpan.FromSeconds(10.0))
    from s in Observable.FromAsync(() => statusChecker.CheckStatus())
    select s;

IDisposable subscription =
    query.Subscribe(status =>
    {
        /* Do something with each `status` as it arrives */
    });
这假设.CheckStatus返回任务


这一切都是通过后台线程完成的,并且是异步的。只需调用订阅。Dispose可停止间隔计时器。简单。

如果检查状态;将运行2秒,每12秒调用一次:\n没错,这与常规计时器不同。您的应用程序可能会在statusCheckingTask完成之前终止。为什么为true?这意味着应用程序必须崩溃才能关闭。@Enigmativity你为什么这么说?至少不是在交互式应用程序中,但我不确定windows服务或web应用程序。欢迎来到toked社区。请插入更多的代码,这样我们可以更好地理解您正在尝试做什么。为什么是真的?这意味着应用程序必须崩溃才能关闭。@Enigmativity:实际上,这取决于哪个线程执行此代码-后台线程将在主线程退出时终止。但我同意,下一步是添加CancellationToken。