✅ Run code in main thread after Task.Run completed?

Hello, I have a long running void function that I execute in a separate thread by calling Task.Run(MyFunction). Now how could I run another function in the main thread when this one ends? Do I need to make an event or something? What are the common approaches to this?
34 Replies
Kouhai
Kouhai2y ago
You'll need a way to schedule a method to be invoked on the main thread the same way BeginInvoke works
1FriendlyDoge
1FriendlyDogeOP2y ago
Cant use BeginInvoke because I use AvaloniaUI instead of winforms :(
Kouhai
Kouhai2y ago
You can use Dispatcher.BeginInvoke
1FriendlyDoge
1FriendlyDogeOP2y ago
also not defined (probably because it isnt cross platform)
Kouhai
Kouhai2y ago
Ah, it's called InvokeAsync in Avalonia
1FriendlyDoge
1FriendlyDogeOP2y ago
Do I just run that in my Task?
Kouhai
Kouhai2y ago
Yes, InvokeAsync will schedule a function to be called on the main thread
1FriendlyDoge
1FriendlyDogeOP2y ago
Seems to have zero effect
if(_auth.ResolveIdentifier() && Storage.DiscordUser != null)
{
Dispatcher.UIThread.InvokeAsync(() =>
{
AuthStatus = "Authenticated as " + Storage.DiscordUser.username + "#" + Storage.DiscordUser.discriminator;
}).Start();
return;
}
if(_auth.ResolveIdentifier() && Storage.DiscordUser != null)
{
Dispatcher.UIThread.InvokeAsync(() =>
{
AuthStatus = "Authenticated as " + Storage.DiscordUser.username + "#" + Storage.DiscordUser.discriminator;
}).Start();
return;
}
AuthStatus is just an ObservableProperty that is bound to a textblock in my UI Every component on its own works, just when I combine them nothing happens, the function ends without the UI being modified
Kouhai
Kouhai2y ago
Don't call .Start
1FriendlyDoge
1FriendlyDogeOP2y ago
Same effect sadly
Kouhai
Kouhai2y ago
Have you checked whether the passed method gets called or not?
1FriendlyDoge
1FriendlyDogeOP2y ago
yup, put Environment.Exit(0); right after for debugging, got called
Kouhai
Kouhai2y ago
So the method is getting called... Also in Avalonia's docs they say it's better to use Post if you don't need to wait for a result to return
1FriendlyDoge
1FriendlyDogeOP2y ago
The weird thing is, it even calls the Environment.Exit when I put it in the dispatch body
if(_auth.ResolveIdentifier() && Storage.DiscordUser != null)
{
Dispatcher.UIThread.Post(() =>
{
AuthStatus = "Authenticated as " + Storage.DiscordUser.username + "#" + Storage.DiscordUser.discriminator;
Environment.Exit(0);
});
return;
}
if(_auth.ResolveIdentifier() && Storage.DiscordUser != null)
{
Dispatcher.UIThread.Post(() =>
{
AuthStatus = "Authenticated as " + Storage.DiscordUser.username + "#" + Storage.DiscordUser.discriminator;
Environment.Exit(0);
});
return;
}
This is so weird And updating AuthStatus in sync works like normal
jcotton42
jcotton422y ago
is there any reason you can't just do
await Task.Run(...);
OtherFunctionYouWantToRun();
await Task.Run(...);
OtherFunctionYouWantToRun();
?
1FriendlyDoge
1FriendlyDogeOP2y ago
My UI would freeze doing that
jcotton42
jcotton422y ago
no it won't await doesn't block the calling thread or at least, it shouldn't unless you've done something wrong
1FriendlyDoge
1FriendlyDogeOP2y ago
Is there any way to make a constructor async, or what is the best way to make it call an async function that runs this?
jcotton42
jcotton422y ago
constructors cannot be async what is this constructor for? A window or page? (or something similar)
1FriendlyDoge
1FriendlyDogeOP2y ago
ViewModel of a page
jcotton42
jcotton422y ago
does the Page have like a loaded event?
1FriendlyDoge
1FriendlyDogeOP2y ago
Pretty sure no Viewmodel constructor is pretty much that
jcotton42
jcotton422y ago
can you link the control you're using? I can't seem to find one called Page
1FriendlyDoge
1FriendlyDogeOP2y ago
I am using https://avaloniaui.net and this is just a viewmodel of a usercontrol I use as page
jcotton42
jcotton422y ago
but otherwise you might need to use the dispatcher I guess
1FriendlyDoge
1FriendlyDogeOP2y ago
The thing is just that the dispatcher doesnt seem to work It can dispatch everything I tried so far, just not UI changes for some reason
jcotton42
jcotton422y ago
if AuthStatus is being bound to, you might not even need the dispatcher
1FriendlyDoge
1FriendlyDogeOP2y ago
<TextBlock
FontFamily="Open Sans"
FontSize="20"
Text="{Binding AuthStatus}"
TextAlignment="Center">
</TextBlock>
<TextBlock
FontFamily="Open Sans"
FontSize="20"
Text="{Binding AuthStatus}"
TextAlignment="Center">
</TextBlock>
jcotton42
jcotton422y ago
also, found this https://docs.avaloniaui.net/guides/basics/accessing-the-ui-thread
You can access the current UI thread via Dispatcher.UIThread. You can either use Post or InvokeAsync, if you want to run a job on the UI thread. Use Post when you just want to start a job, but you don't need to wait for the job to be finished and you don't need the result. If you need to wait for the result, then use InvokeAsync instead.
it looks you should be using Post, or using InvokeAsync, but also awaiting it
1FriendlyDoge
1FriendlyDogeOP2y ago
Already tried both of those, both dont work
jcotton42
jcotton422y ago
I also see nothing about Start need to dip, have a work meeting starting
1FriendlyDoge
1FriendlyDogeOP2y ago
I copied 1:1 from that page, both approaches do nothing Alright, thank you for your help (Bump) $close
MODiX
MODiX2y ago
Use the /close command to mark a forum thread as answered

Did you find this page helpful?