How to prevent a async task method get called concurrently

时间:2017-06-15 09:44:27

标签: c# xamarin async-await locking

I have a async task method which will be accessed on both foreground and background. In foreground, where user call this method via a button whereas in the background I have a timer triggering the method in some interval.

I tried put lock but it gives exception await can not be inside the lock statement.

    public static async Task<CommonResult<IEnumerable<AttendanceDTO>>> DownloadAttendanceAsync(string selectedDate, int siteId)
    {
        try
        { 
            if (new AttendanceBLL().IsLocalDataAvailable(siteId, DateTime.Parse(selectedDate)))
                return new CommonResult<IEnumerable<AttendanceDTO>>() { IsSuccess = true, Data = null };

            var queue = new EntityQueueBLL();
            //var latestUpdatedOn = queue.GetMaxUpdated(siteId, EntityIDEnum.Attendance);
            var url = string.Format(Constants.PathPullAttendance, selectedDate, siteId);
            var result = await new HttpRequestClient().GetRequest<IEnumerable<AttendanceDTO>>(url);

            if (!result.IsSuccess)
                return new CommonResult<IEnumerable<AttendanceDTO>>() { IsSuccess = false, Data = null, ErrorMessage = result.ErrorMessage };

            if (result.Data != null && result.Data.Count() > 0)
            {
                var maxUpdatedOn = result.Data.Max(x => DateTime.Parse(x.UpdatedOn));
                queue.Add(siteId, result.Data, result.Data.Count(), EntityIDEnum.Attendance, EntityType.Attendance, maxUpdatedOn);
            }

            return new CommonResult<IEnumerable<AttendanceDTO>> { IsSuccess = true, Data = result.Data }; 
        }
        catch (Exception e)
        {
            return new CommonResult<IEnumerable<AttendanceDTO>> { IsSuccess = false, Data = null, ErrorMessage = "Download Error" };
        }
    }

3 个答案:

答案 0 :(得分:4)

  

我尝试了把锁但是它给了异常await不能在lock语句中。

await - 兼容等效lockSemaphoreSlim

private static SempahoreSlim _mutex = new SemaphoreSlim(1);
public static async Task<CommonResult<IEnumerable<AttendanceDTO>>> DownloadAttendanceAsync(string selectedDate, int siteId)
{
  await _mutex.WaitAsync();
  try
  { 
    ...
  }
  catch (Exception e)
  {
    return new CommonResult<IEnumerable<AttendanceDTO>> { IsSuccess = false, Data = null, ErrorMessage = "Download Error" };
  }
  finally
  {
    _mutex.Release();
  }
}

答案 1 :(得分:0)

我用

AsyncLazy

对于我的初始化,可以从不同的线程调用。该任务仅被调用一次,其他呼叫者等待它。

答案 2 :(得分:-3)

try the below:

await Task.Delay(2000);