I have a Parent and a Child Razor component, the child has a Parameter that is of type EventCallback. If I have an async Task called from a synchronous function (using Task.Run) after I await the .InvokeAsync no further lines of code run.
Parent Component:
@page "/"
@inject NavigationManager navigationManager
<PageTitle>Home</PageTitle>
<Child OnChildClick="() => OnChildClick(newMessage)" />
<p>@_message</p>
@code
{
private string _message = "test";
private string newMessage = "new test";
private void OnChildClick(string message)
{
_message = message;
InvokeAsync(StateHasChanged);
}
}
Child Component
<h3>Child</h3>
<MudButton OnClick="OnClick">Click me</MudButton>
@code {
[Parameter]
public EventCallback OnChildClick { get; set; }
private void OnClick()
{
Task.Run(() => OnClickDoThing());
}
private async Task OnClickDoThing()
{
await OnChildClick.InvokeAsync();
Console.WriteLine("Child clicked"); // This will not be called, why?
}
}
As you can see I commented on the Console.WriteLine. If I instead make the OnClick function async and just await the OnClickDoThing it works fine, but in a Task.Run, it doesn't. Can someone help me and explain the reason behind this? I assume I don't understand Task.Run well enough.
Task.Run()
returns a new Task
. A task won't proceed past the first await where IsCompleted
is false without someone awaiting it at a higher level. That's why it works in one case and not the other.
You can try this out in a console application where your dependencies will be simpler and you'll get a better idea of how things are working, or not as the case might be.
Disclaimer: assume default task scheduler and other shenanigans.