I'm migrating an in-process Azure Function to the isolated worker model in C# on .NET 10 with Azure Functions v4. The function currently starts a long-running operation using a fire-and-forget pattern such as `_ = Task.Run(() => FunctionX);` and then returns immediately. I use `ILogger` with configuration in `appsettings.json`. Logging works before the function returns, but messages generated inside `FunctionX` are no longer written after the main invocation completes. This did not happen with the in-process model. What is the recommended way to run this work reliably and preserve its logging?
3 Answers
For genuinely long-running work, don’t keep it as an untracked background task inside a function invocation. Put a work item on a queue or use Durable Functions, then process it in a separate function. That gives the work its own retry and execution lifecycle, and the logs are emitted while that worker invocation is active. It is also much safer if the host scales out or restarts.
If you only need to run asynchronous code, `Task.Run` is generally unnecessary in an Azure Function. Make the method asynchronous and await it directly. If you intentionally return before the work completes, there is no guarantee that the isolated worker will keep the process alive or flush the log provider, even if the same pattern appeared to work in the in-process model.
The main issue is the fire-and-forget pattern, not usually a difference in the logging APIs. Once the function returns, the invocation scope can be disposed and the worker may be recycled or shut down, so the detached task is not guaranteed to finish. Its `ILogger` scope and other dependencies may no longer be valid either. Await the operation if it can complete within the function timeout: `await FunctionX();`. Also pass through the function’s cancellation token and handle cancellation cleanly.

That explains why the logs stop exactly when the function returns. I was starting the task with `Task.Run` and never awaiting it.