2017-03-28 11 views
1

Task에 지연을 구현하는 최선의 방법을 알아 내려고 노력하고 있습니다. 지연 후에 다시 같은 작업을 시도합니다.Task.Delay와 재귀 호출 사용하기

내 응용 프로그램은 모바일 장치가 서버와 데이터를 동기화 한 후에 데이터베이스에서 보고서를 생성하는 서버입니다. 그러나 다른 사용자가 최근 보고서 생성 방법을 호출 한 경우 일정 기간 동안 일시 중지 한 다음 다시 실행 해보십시오.

이가 확인에 실패하면 다음 작업이 바로 끝날 것

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

x 분 후에 작업을 실행하는 것이 좋습니다. 'Task.Delay (TimeSpan.FromMinutes (2));'는 시나리오에서 좋은 것은 아닌 스레드를 차단합니다. –

+0

@ i.net 메서드 자체가 어쨌든 클라이언트에서 비동기 적으로 호출되므로 라인 아래로 직접적인 문제가 발생하지 않을 것입니다. 어떤 문제가이 시점에서 스레드를 차단할 수 있습니까? – Takarii

+1

나는이 코드가 무엇을해야하는지 전혀 이해하지 못한다. (당신의 설명이있다하더라도) 당신의'Task.Delay (TimeSpan.FromMinutes (2)); '호출은 실제로 그것이 완료되기를 기다리지 않기 때문에 아무 것도하지 않습니다. – Evk

답변

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; 
    } 

} 
+0

작업을 완료하는 데 10 초 이상 걸릴 수있는 좋은 기회이므로 5 분의 시간 간격을 늘리면 큰 영향을 미칩니 까? 나는 타이머가 더 길어질수록 일관성이 없어 질 수 있다는 것을 알고있다 – Takarii

+0

Nope! 그것은 큰 영향을 미치지 않을 것입니다. 시간을 원하는대로 설정할 수 있습니다. 위의 코드는 x 분/초마다 반복적으로 실행됩니다. –

+0

여러 타이머를 사용하면 스레드 풀이 가득 차게되어 큐 풀이 대기합니다. 적은 타이머를 사용하는 경우 응용 프로그램에서 타이머를 사용하는 데 문제가 없습니다. –