使用Task.Delay和递归调用

时间:2017-03-28 12:17:13

标签: c# recursion task delay

我试图找出将延迟实施到Task的最佳方法,以便在延迟之后再次调用自己来尝试同样的工作。

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

这是我目前的尝试

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

}

最初如果检查失败,那么任务就会结束​​。这阻止了2个用户同时访问数据库,并导致生成重复的报告。但问题是,如果2个用户在同一个窗口内同步,则第二个用户报告将不会被发送,直到完成另一个同步呼叫。

延迟应该让服务器有时间完成生成报告并在通过调用自己请求下一批之前更新数据库。

我是不是太复杂了?我很担心,如果报告需要很长时间来处理,它可能会通过多个循环来破坏系统资源

1 个答案:

答案 0 :(得分:0)

以下示例递归地每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;
    }

}