C# 使用Task.Delay和递归调用

C# 使用Task.Delay和递归调用,c#,recursion,task,delay,C#,Recursion,Task,Delay,我正试图找出在任务中实现延迟的最佳方法,这样在延迟之后,它会再次调用自己来尝试相同的工作 我的应用程序是一个在移动设备与服务器同步数据后从数据库生成报告的服务器,但是如果其他用户最近调用了报告生成方法,我希望它暂停一段时间,然后再次尝试运行 这是我目前的尝试 private static DateTime _lastRequest = Datetime.MinValue; public async void IssueReports() { await Task.Run(() =&g

我正试图找出在
任务
中实现延迟的最佳方法,这样在延迟之后,它会再次调用自己来尝试相同的工作

我的应用程序是一个在移动设备与服务器同步数据后从数据库生成报告的服务器,但是如果其他用户最近调用了报告生成方法,我希望它暂停一段时间,然后再次尝试运行

这是我目前的尝试

private static DateTime _lastRequest = Datetime.MinValue;


public async void IssueReports()
{
    await Task.Run(() =>
    {
        if (DateTime.Now < _lastRequest + TimeSpan.FromMinutes(3)) //checks to see when a user last completed this method
        {
            Task.Delay(TimeSpan.FromMinutes(2)); 
            IssueReports(); //calls itself again after the delay
            return;
        }
    });

    //code to generate reports goes here
    _lastRequest = DateTime.Now; //updates last request into the static variable after it has finished running

}
private static DateTime\u lastRequest=DateTime.MinValue;
公共异步void IssueReports()
{
等待任务。运行(()=>
{
if(DateTime.Now<\u lastRequest+TimeSpan.FromMinutes(3))//检查用户上次完成此方法的时间
{
任务延迟(时间跨度从分钟(2));
IssueReports();//延迟后再次调用自身
返回;
}
});
//生成报告的代码在这里
_lastRequest=DateTime.Now;//在最后一个请求完成运行后将其更新到静态变量中
}
最初,如果检查失败,那么任务将结束。这防止了2个用户同时访问数据库,并导致生成重复的报告。但是,问题是,如果两个用户在同一个窗口内同步,则在另一个同步调用完成之前,不会发送第二个用户报告

延迟应该给服务器一段时间,以便在通过调用自身请求下一批之前完成生成报告和更新数据库


我把事情复杂化了吗?我担心,如果报表需要很长时间才能处理,那么它可能会使用多个循环对系统资源造成冲击。下面的示例是每10秒递归运行一次后台服务。仅当您认为任务将在10秒内完成时,才建议使用此方法

public frm_testform()
{

    InitializeComponent();

    dispatcherTimer_Tick().DoNotAwait();

}

private async Task dispatcherTimer_Tick()
{
    DispatcherTimer timer = new DispatcherTimer();
    TaskCompletionSource<bool> tcs = null;
    EventHandler tickHandler = (s, e) => tcs.TrySetResult(true);

    timer.Interval = TimeSpan.FromSeconds(10);
    timer.Tick += tickHandler;
    timer.Start();

    while (true)
    {
        tcs = new TaskCompletionSource<bool>();

        await Task.Run(() =>
        {
       // Run your background service and UI update here
        await tcs.Task;
    }

}
public frm_testform()
{
初始化组件();
Dispatchermer_Tick().DoNotAwait();
}
专用异步任务分派器_Tick()
{
调度程序计时器=新调度程序();
TaskCompletionSource tcs=null;
EventHandler=(s,e)=>tcs.TrySetResult(true);
timer.Interval=从秒开始的时间跨度(10);
timer.Tick+=tickHandler;
timer.Start();
while(true)
{
tcs=新任务完成源();
等待任务。运行(()=>
{
//在此处运行后台服务和UI更新
等待tcs任务;
}
}

以下示例以递归方式每10秒运行一次后台服务。仅当您认为任务将在10秒内完成时,才建议使用此方法

public frm_testform()
{

    InitializeComponent();

    dispatcherTimer_Tick().DoNotAwait();

}

private async Task dispatcherTimer_Tick()
{
    DispatcherTimer timer = new DispatcherTimer();
    TaskCompletionSource<bool> tcs = null;
    EventHandler tickHandler = (s, e) => tcs.TrySetResult(true);

    timer.Interval = TimeSpan.FromSeconds(10);
    timer.Tick += tickHandler;
    timer.Start();

    while (true)
    {
        tcs = new TaskCompletionSource<bool>();

        await Task.Run(() =>
        {
       // Run your background service and UI update here
        await tcs.Task;
    }

}
public frm_testform()
{
初始化组件();
Dispatchermer_Tick().DoNotAwait();
}
专用异步任务分派器_Tick()
{
调度程序计时器=新调度程序();
TaskCompletionSource tcs=null;
EventHandler=(s,e)=>tcs.TrySetResult(true);
timer.Interval=从秒开始的时间跨度(10);
timer.Tick+=tickHandler;
timer.Start();
while(true)
{
tcs=新任务完成源();
等待任务。运行(()=>
{
//在此处运行后台服务和UI更新
等待tcs任务;
}
}

最好在x分钟后使用计时器运行任务。
Task.Delay(TimeSpan.FromMinutes(2));
将阻止线程,这在您的场景中不是一件好事。@i.net无论如何,该方法本身都是从客户端异步调用的,因此它不会直接导致问题-我不认为。此时阻止线程会导致什么问题?我完全不明白这段代码应该做什么(即使有你的解释)但是要注意你的
Task.Delay(TimeSpan.FromMinutes(2))
调用实际上什么都不做,因为你没有等待它完成。@Evk抱歉,我错过了那行的等待部分,正如我说的,我不理解代码的意图,但至少从删除
等待任务开始。完全运行
。然后在
任务之前添加
等待
。延迟
。也许它会做什么如果需要,最好在x分钟后使用计时器运行任务。
Task.Delay(TimeSpan.FromMinutes(2));
将阻止线程,这在您的场景中不是一件好事。@i.net无论如何,该方法本身都是从客户端异步调用的,因此它不会直接导致问题-我不认为。此时阻止线程会导致什么问题?我完全不明白这段代码应该做什么(即使有你的解释)但是要注意你的
Task.Delay(TimeSpan.FromMinutes(2))
调用实际上什么都不做,因为你没有等待它完成。@Evk抱歉,我错过了那行的等待部分,正如我说的,我不理解代码的意图,但至少从删除
等待任务开始。完全运行
。然后在
任务之前添加
等待
。延迟
。也许它会做什么你想。很有可能任务需要10秒以上才能完成,那么将时间间隔增加到5分钟会有很大影响吗?我知道计时器运行的时间越长,可能会变得不一致。不会有很大影响。你可以根据自己的意愿设置时间。上述代码将每x分/秒重复运行一次。Mu多个计时器可能会导致线程池已满,并将其排队。如果您使用较少的计时器,则在应用程序中使用计时器没有问题。很可能任务需要10秒以上的时间才能完成,因此将间隔增加到5分钟会产生很大影响吗?我知道计时器可能会变得不一致它们运行的时间越长不!不会有太大影响。您可以根据自己的意愿设置时间。上述代码将每x分钟/秒重复运行一次。多个计时器可能会导致线程池已满,并将其排队。如果您使用的时间较少