Yup, I missed an await
.
Nothing new. No one else to blame.
But why did it take so long to find it? Because the app worked locally but failed on the pipeline, I thought it was a pipeline problem! Is the Azure pipeline set up in some way that doesn’t wait for my dotnet run
command to finish? Does an error occur that is not properly logged and therefore not visible on the pipeline run? Do I need to use a different Azure DotNetCoreCLI
task or instead start the program with a shell script? Am I losing my mind?
Asynchronous programming can be tricky, especially when tasks are not awaited properly. This often leads to unexpected behavior, especially when running applications in different environments (like Rider or other IDEs vs. the terminal or CI/CD pipelines).
My case
static void Main(string[] args)
{
SomeProcess(); // Missing await
}
static async Task SomeProcess() {
await SomeOtherProcess();
}
My Main
function called a process that had a few asynchronous tasks. On the pipeline, observing the logs, I saw that the pipeline task running the program would be completed at random times, rarely letting the .NET program complete a full run.
That is because the call in the Main
function to a process initiating asynchronous tasks never waited for that process to complete, and the Main
function run finished whenever it pleased.
But why did the .NET program always run fully in the Rider IDE?
Seems like Rider might have a specific run environment. Rider might implicitly handle unawaited tasks, potentially waiting for asynchronous tasks to complete before terminating the run process, allowing the app to seem to run fully. An IDE might introduce additional debugging or process-wait mechanisms that make the application appear to be more forgiving in certain cases.
When running in the terminal or CI/CD pipelines, there is no "help" from Rider or other IDEs. The application exits immediately after the Main
method finishes, even if tasks are still running in the background. Without await
, these background tasks won’t finish before the application ends, leading to errors or incomplete operations.
How I fixed it
First, it was important to start my application by running the dotnet run
command from the terminal, and not an IDE. This way it was clear that the problem was in the application code, not in my pipeline setup.
Then, I had to dig a bit through the code to find where exactly I was not handling the asynchronous processes properly. Once I found it, I added the missing await
statement. And it worked like magic.
static async Task Main(string[] args)
{
await SomeProcess();
}
static async Task SomeProcess() {
await SomeOtherProcess();
}
Lessons learned
- Always
await
asynchronous operations. - Test in multiple environments: test the run of your application in a terminal or similar environment to where it is failing.
- Do not rely just on the IDE run processes to verify the functionality of your program.
Top comments (0)