UI freezes when multiple asynchronous operations (async/await)

Asked 2 years ago, Updated 2 years ago, 111 views

Hello, I am currently creating a program using asynchronous processing on C#.

As a background, I wanted to create something that continuously writes certain values into the memory space of an external device.
If you check the check box, you can use async/await during the check and continue writing with asynchronous processing.

However, if you make several of them with the same structure and check about three, the UI will freeze.
The application does not appear to have dropped because it can be written to memory.

What are the possible causes of UI hardening?

#region Always UAV

    private async void kpUV_CheckedChanged (object sender, EventArgse)
    {
        if(kpUV.Checked)
        {
            while(kpUV.Checked)
            {
                ulong targetClient=0x21A8164+ (0x17010*(ulong)kpSelectClient.Value);
                PS4.WriteMemory(this.processID, targetClient+0x714, new byte[]{0x01}); // UAV1
                PS4.WriteMemory(this.processID, targetClient+0xBC74, new byte[]{0x01}); // UAV2
                PS4.WriteMemory(this.processID, targetClient+0x16F9C, new byte[]{0x01}); // UAV3
                wait Task.Run() = > {Thread.Sleep(150);};
            }
        }
        else
        {
            ulong targetClient=0x21A8164+ (0x17010*(ulong)kpSelectClient.Value);
            PS4.WriteMemory(this.processID, targetClient+0x714, new byte[]{0x00}); // UAV1
            PS4.WriteMemory(this.processID, targetClient+0xBC74, new byte[]{0x00}); // UAV2
            PS4.WriteMemory(this.processID, targetClient+0x16F9C, new byte[]{0x00}); // UAV3
        }
    }

    #endregion

    # region Always VSAT

    private async voidkpVSAT_CheckedChanged (object sender, EventArgse)
    {
        if(kpVSAT.Checked)
        {
            while(kpVSAT.Checked)
            {
                ulong targetClient=0x21A8164+ (0x17010*(ulong)kpSelectClient.Value);
                PS4.WriteMemory(this.processID, targetClient+0x718, new byte[]{0x01}); // VSAT1
                PS4.WriteMemory(this.processID, targetClient+0xBC78, new byte[]{0x01}); // VSAT2
                PS4.WriteMemory(this.processID, targetClient+0x16FA0, new byte[]{0x01}); // VSAT3
                wait Task.Run() = > {Thread.Sleep(150);};
            }
        }
        else
        {
            ulong targetClient=0x21A8164+ (0x17010*(ulong)kpSelectClient.Value);
            PS4.WriteMemory(this.processID, targetClient+0x718, new byte[]{0x00}); // VSAT1
            PS4.WriteMemory(this.processID, targetClient+0xBC78, new byte[]{0x00}); // VSAT2
            PS4.WriteMemory(this.processID, targetClient+0x16FA0, new byte[]{0x00}); // VSAT3
        }
    }

    #endregion

    # region Laser locator

    private async void kpLaserLocator_CheckedChanged (object sender, EventArgse)
    {
        if(kpLaserLocator.Checked)
        {
            while(kpLaserLocator.Checked)
            {
                ulong targetClient=0x21A8164+ (0x17010*(ulong)kpSelectClient.Value);
                PS4.WriteMemory(this.processID, targetClient+0x782, new byte[]{0x01}); // Point laser1
                PS4.WriteMemory(this.processID, targetClient+0xBCE2, new byte[]{0x01}); // Point laser2
                PS4.WriteMemory(this.processID, targetClient+0x17740, new byte[]{0x01}); // Point laser3
                wait Task.Run() = > {Thread.Sleep(150);};
            }
        }
        else
        {
            ulong targetClient=0x21A8164+ (0x17010*(ulong)kpSelectClient.Value);
            PS4.WriteMemory(this.processID, targetClient+0x782, new byte[]{0x00}); // Point laser1
            PS4.WriteMemory(this.processID, targetClient+0xBCE2, new byte[]{0x00}); // Point laser2
            PS4.WriteMemory(this.processID, targetClient+0x17740, new byte[]{0x00}); // Point laser3
        }
    }

    #endregion

If you check about three boxes on the left, the UI will freeze.

c# multi-threaded gui

2022-09-29 21:40

3 Answers

Verified with Visual Studio 2017, .NET Framework 4.5 Form application.

When I first tried to move a similar code without PS4.WriteMemory, I did not see the symptom of heavy operation even if I put in three check boxes.
There seems to be no problem using async, wait, and Task.
Just in case, I called Thread.CurrentThread.ManagedThreadId where PS4.WriteMemory was called, and the thread ID was also checked, but it was all "1", so it was the main thread.
If it is running on the same thread, there should be no problem if PS4.WriteMemory is not thread safe.

The possible possibility is simply that PS4.WriteMemory is taking a long time to process.
The code sleeps 150 ms, so if PS4.WriteMemory×n processing exceeds 150 ms, the UI will not respond because the processing time exceeds the waiting time.
When I tried placing three PS4.WriteMemory as Thread.Sleep(70), I almost lost control when I checked three boxes.

The quick solution is to extend the sleep time in Task.
If the wait time is much larger than the processing time, it may be heavy, but it can be operated.
A fundamental solution is to process PS4.WriteMemory within System.Threading.Timer.
Create a Timer for each check box to control the start and stop of the Timer.
Exclusive control is required because it is a separate thread process.
Also, call Timer.Dispose() to release the application.


2022-09-29 21:40

It's not the cause, it's the investigation method.Try debugging with these information.

Debugging Multithreaded Applications
Concurrent Visualizer

Application Verifier

Take a mini dump from the Task Manager or Process Explorer and investigate the dump.
How to Capture a Minidump: Let Me Count the Ways

This is also an explanation of various techniques.Parts 1 through 5.
Part 1: Windows Debugging Techniques - Debugging Application Crash (Windbg)


2022-09-29 21:40

If it doesn't seem to be resolved, just for your information...
If it is wrong, please correct it.

I remember that using Thread.Sleep() stops the UI that is running on the main.
I think you can use Task.Delay() instead of Thread.Sleep() to solve this problem.
I would appreciate it if you could change awitTask.Run()=>{Thread.Sleep(150); to awitTask.Delay(150); in the code to verify the desired behavior.


2022-09-29 21:40

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.