1

I have a task which I fire off to do some periodic work, although I've noticed it randomly stops executing.

Task.Factory.StartNew(gameProcessor.ProcessAsync, CancellationToken.None,
    TaskCreationOptions.LongRunning, TaskScheduler.Default);

I understand I'm not awaiting the task but I have implemented a try catch block for error handling. Even with this I can confirm my breakpoint never hits the catch statement, so I'm confused to what's going on.

Method:

public async Task ProcessAsync()
{
    while (true)
    {
        try 
        {
            await _roomRepository.RunPeriodicCheckAsync();
            await Task.Delay(500);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
    }
}
Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
konata7533
  • 11
  • 1
  • What is the type of the application? Is it [ASP.NET](https://blog.stephencleary.com/2014/06/fire-and-forget-on-asp-net.html) by any chance? – Theodor Zoulias Mar 19 '22 at 16:11
  • @TheodorZoulias It is a C# console application in .NET 6.0 – konata7533 Mar 19 '22 at 16:13
  • 2
    As a side note, the `Task.Run` is preferable to the `Task.Factory.StartNew`. The former understands async delegates, but the later [doesn't](https://devblogs.microsoft.com/pfxteam/task-run-vs-task-factory-startnew/). And in your case the delegate (`ProcessAsync`) is async. This is unlikely to be relevant to your problem though. – Theodor Zoulias Mar 19 '22 at 16:14
  • @TheodorZoulias thanks for the tip. I believe Task.Run uses a thread from the thread pool, specifying extra options such as LongRunning means it uses its own dedicated thread which would be better in this context. – konata7533 Mar 19 '22 at 16:17
  • If this is a console app how do you keep it running if you don't away `StartNew` result? Once the `Main` method finishes your console app will stop and exit and so `ProcessAsync` method. – Artur Mar 19 '22 at 16:20
  • @Artur that isn't the last call in my application, I was just trying to give a minimal example, I don't think any of the code after this matters to the specific problem, whatever is causing it seems to be what is happening inside the actual Task. – konata7533 Mar 19 '22 at 16:21
  • 2
    True, but the `ProcessAsync()` in not going to run on the dedicated thread for long. As soon as the first `await` is reached, the dedicated thread will terminate. The continuation after the `await` will run on whatever thread was chosen by the awaitable. In order to stay on the dedicated thread you should install a properly implemented `SynchronizationContext`, like Stephen Cleary's [`AsyncContext`](https://github.com/StephenCleary/AsyncEx/wiki/AsyncContext). – Theodor Zoulias Mar 19 '22 at 16:23
  • Could you try converting the asynchronous `ProcessAsync` method to a synchronous method, with a `void` return type, `Wait` instead of `await` the inner calls, and see if it makes any difference? – Theodor Zoulias Mar 19 '22 at 16:26
  • I would suggest to use a `Timer` that calls `await _roomRepository.RunPeriodicCheckAsync();` - seems a lot easier approach, since what you are creating actually is a timer. Use for instance `System.Timers.Timers`. – Poul Bak Mar 19 '22 at 17:20
  • BTW, if the app crashes, you should be able to find the crash event with helpful info in Windows Event Viewer. – Artur Mar 19 '22 at 18:35
  • Could it be being garbage collected if you've not kept a reference to it? – Steve Smith Oct 28 '22 at 15:52

0 Answers0