3

As per Thread Abort Exception in.NET 4.5, I should use QueueBackgroundItem.

For some reason, the queued background item should not be started directly (the same user has just requested data which had to be fetched directly from EWS, so the Exchange server assumes that doing a full sync directly afterwards is a malicious DoS attempt on the EWS), but only a certain TimeSpan after the item has been queued.

So I made the following:

    public static void DoAfter(TimeSpan waitFor, Action<Logger> action)
    {
        HostingEnvironment.QueueBackgroundWorkItem(async ct =>
        {
            await Task.Delay(waitFor);
            DatabaseLogger logger = new DatabaseLogger(DebugLevel.TOSQL, db);
            logger.Log("Executing " + action.Method.Name + ", " + DateTime.Now.ToLongTimeString());
            try
            {
                action(logger);
                logger.Log("Successfully executed " + action.Method.Name + ", " + DateTime.Now.ToLongTimeString());
            }
            catch (Exception e)
            {
                logger.Log("Error in " + action.Method.Name + ": " + e.Message + ", " + DateTime.Now.ToLongTimeString());
            }
            finally
            {
                logger.CloseDatabase();
            }
        });
    }

For some reasons described at Why use async with QueueBackgroundWorkItem?, "you shouldn't use async here".

But with "Instead of using Thread.Sleep use Task.Delay", and await task.Delay giving semantic compiler error "await operator can only be used within an async lambda expression", how would I delay the BackgroundWorkItem without clogging the BackgroundWorkItem queue?

Community
  • 1
  • 1
Alexander
  • 19,906
  • 19
  • 75
  • 162

1 Answers1

3

I think your situation here is different than that of the SO question you posted. In that question, the OP was wrapping an already async method (e.g. one that already returned a Task) with an async lambda (that wasn't actually his question though). So, as I read the advice, what he was doing was redundant, where he could just pass in the LongRunningMethod.

I think the code you have here is acceptable, although there are some pitfalls that can apply to using async lambdas, but they're usually connected with using them for Actions because the Action is a void returning delegate. Some more reading on that here.

CodingGorilla
  • 19,612
  • 4
  • 45
  • 65