Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In C# Winforms What is the most precise method of having an asynchronous method guarantee its own execution on the UI thread?

In doing my research here there seem to be about a million different ways to accomplish this, but the pros and cons of each are less unclear. One possibility that seems to accomplish what I'm after is:

private async Task SomeMostlyUIMethod(byte[] someParam = null)
{
    if (InvokeRequired)
    {
        Task result = Task.Run(() => Invoke((Action)(async () => await SomeMostlyUIMethod(someParam))));
        await result;
        return;
    }
    else
    {
        // do some stuff
    }
}

That seems to work, it feels like there should be a more clear solution for this. I'm not invoking on a per control modified basis because the method modifies a large number of different UI components, but also need to keep the method asynchronous since it has some expensive non-ui tasks it carries out as well.

like image 228
Russell Bearden Avatar asked Dec 12 '25 14:12

Russell Bearden


2 Answers

to make work item will be executed on UI thread, you probably need the current synchronization context:

factory = new TaskFactory(TaskScheduler.FromCurrentSynchronizationContext());

and use that factory to StartNew any task involved in GUI control updating.

like image 50
Bob Dust Avatar answered Dec 15 '25 04:12

Bob Dust


You need to launch the async operation from an UI thread (main thread):

await Task.Run(DoYourStuffAsync);

This is equivalent to:

await Task.Run(DoYourStuffAsync).ConfigureAwait(true);

If the boolean argument of ConfigureAwait (bool continueOnCapturedContext) is true, the code that is below the await (also called continuation) will be executed in the calling thread (UI thread).

What I suggest is to do all your processing in an async way, create an outcome object, and then update the UI element in the continuation with the outcome object. In this way you are using the UI thread only for UI stuff.

like image 41
ilBarra Avatar answered Dec 15 '25 03:12

ilBarra