Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.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# Windows服务未及时启动-是否将初始工作负载传递给计时器?_C#_.net_Service_Timer_Windows Services - Fatal编程技术网

C# Windows服务未及时启动-是否将初始工作负载传递给计时器?

C# Windows服务未及时启动-是否将初始工作负载传递给计时器?,c#,.net,service,timer,windows-services,C#,.net,Service,Timer,Windows Services,我正在运行一个Windows服务,它执行一个大型数据迁移过程(第一次运行时需要10分钟以上)。目前,我的服务在启动时运行一次,之后每4小时运行一次。类似这样的内容(节选): 问题是,在部署和运行Windows服务后,Windows服务错误为“服务未及时响应启动或控制请求” 我意识到我可以从OnStart中删除对DoMigration()的初始调用,让服务快速启动——但这样的话,工作将在4小时内无法完成,这是不可取的 我有没有办法为第一个计时器设置一个不同的时间间隔(可能是30秒或60秒),然后再

我正在运行一个Windows服务,它执行一个大型数据迁移过程(第一次运行时需要10分钟以上)。目前,我的服务在启动时运行一次,之后每4小时运行一次。类似这样的内容(节选):

问题是,在部署和运行Windows服务后,Windows服务错误为“服务未及时响应启动或控制请求”

我意识到我可以从OnStart中删除对DoMigration()的初始调用,让服务快速启动——但这样的话,工作将在4小时内无法完成,这是不可取的

我有没有办法为第一个计时器设置一个不同的时间间隔(可能是30秒或60秒),然后再设置一个单独的4小时周期间隔?基本上,我希望将工作负载推出OnStart以防止错误,但我仍然希望在启动后尽快运行它


这可能吗?这是最好的方法吗?如果您有任何建议,我们将不胜感激。

问题是,
OnStart
方法需要在相当短的时间内(也许30秒?)完成,然后Windows才会认为出现了问题。一个简单的解决方案是在第一次运行时快速启动计时器,然后从事件内部重新配置计时器,以便在4小时内再次运行:

protected override void OnStart(string[] args)
{
    // Set up timer
    int initialIntervalSync = 10; // 10 seconds
    timer = new System.Timers.Timer();
    timer.Interval = initialIntervalSync * 1000;
    timer.Elapsed += new System.Timers.ElapsedEventHandler(this.OnTimer);
    timer.Start();    
}

public void OnTimer(object sender, System.Timers.ElapsedEventArgs args)
{
    //Reset timer interval
    int intervalSync = 14400; // 4 hours default
    timer.Interval = intervalSync * 1000;

    this.DoMigration();
}

首先,解决这个问题的最简单方法是使用
async
/
wait

protected override void OnStart(string[] args)
{
    // Storing the returned Task in a variable is a hack
    // to suppresses the usual compiler warning.
    var _ = DoMigrationLoop();
}

private async Task DoMigrationLoop()
{
    while (true)
    {
        await Task.Run(() => this.DoMigration());
        await Task.Delay(TimeSpan.FromHours(4));
    }
}
这会导致
DoMigration()
方法立即在单独的线程中执行,然后每四小时执行一次。请注意,由于原始的
domingrationloop()
方法调用在第一次
wait
调用时立即返回,因此
OnStart()
方法本身根本没有延迟


可以根据需要随意添加任务取消、异常处理和其他细节。:)

设置另一个间隔几秒钟的计时器进行数据迁移。为什么不使用后台线程进行数据迁移?
protected override void OnStart(string[] args)
{
    // Storing the returned Task in a variable is a hack
    // to suppresses the usual compiler warning.
    var _ = DoMigrationLoop();
}

private async Task DoMigrationLoop()
{
    while (true)
    {
        await Task.Run(() => this.DoMigration());
        await Task.Delay(TimeSpan.FromHours(4));
    }
}