Forum General

C# Rather than Xamarin.Forms question: Is that the right way to cancel a task?

jddjdd USMember ✭✭✭

I need to do a long-running operation each time the user changes an Entry. So I planned to cancel the task if it is already running and start it again. Please find my code below.
Is it the right way to do it? Is there a simpler way to do it? The task seems to go on even if it is canceled.
ViewModel:

// THE METHOD THAT CHECKS IF THE TASK IS ALREADY RUNNING, CANCELS IT AND STARTS IT AGAIN
        private async Task resetSolarSystem(DateTime dt)
        {
#if DEBUG
                    System.Diagnostics.Debug.WriteLine("\nresetSolarSystem");
#endif
            if (solarSystemTask != null )
            {
                if(solarSystemTask.IsCompleted)
                {
                    SolarSystem ss = solarSystemTask.Result;
                    if(ss.UTC!=dt)
                    {
#if DEBUG
                        System.Diagnostics.Debug.WriteLine("\nNeed to make a new operation");
#endif
                        cts = new CancellationTokenSource();
                        solarSystemTask = makeSolarSystem(dt, cts.Token);
                    }
                }
                else
                {
#if DEBUG
                    System.Diagnostics.Debug.WriteLine("\nNeed to cancel the running task");
#endif
                    cts.Cancel();
                    cts = new CancellationTokenSource();
                    solarSystemTask = makeSolarSystem(dt, cts.Token);
                }
            }
            else
            {
#if DEBUG
                System.Diagnostics.Debug.WriteLine("\nNeed to start the operation for the first time");
#endif
                cts = new CancellationTokenSource();
                solarSystemTask = makeSolarSystem(dt, cts.Token);
            }
        }
// THE ASYNC TASK
        private static async Task<SolarSystem> makeSolarSystem(DateTime dt, CancellationToken ct)
        {
#if DEBUG
            System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();
            stopWatch.Start();
#endif
            Task<SolarSystem> ssToReturnTask;
            ssToReturnTask = Task<SolarSystem>.Run(() =>
            {
                System.Diagnostics.Debug.WriteLine("\nLong running operation starts");
                // THE LONG-RUNNING OPERATION:
                SolarSystem ss = new SolarSystem(dt);
                System.Diagnostics.Debug.WriteLine("\nLong running operation is finished");
                return ss;
            }, ct);
            SolarSystem ssToReturn = await ssToReturnTask;
#if DEBUG
            stopWatch.Stop();
            TimeSpan ts = stopWatch.Elapsed;
            System.Diagnostics.Debug.WriteLine("ms " + ts.TotalMilliseconds);
#endif
            return ssToReturn;
        }

This is the output:

[0:]
resetSolarSystem
[0:]
Need to start the operation for the first time
[0:]
Long running operation starts
(...)
06-26 13:48:31.653 I/Choreographer(21747): Skipped 85 frames! The application may be doing too much work on its main thread.
06-26 13:48:31.832 I/OpenGLRenderer(21747): Davey! duration=1599ms; Flags=0, IntendedVsync=4842714656434, Vsync=4844131323044, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=4844135837802, AnimationStart=4844135963843, PerformTraversalsStart=4844138266968, DrawStart=4844248419051, SyncQueued=4844296502385, SyncStart=4844296610197, IssueDrawCommandsStart=4844304478947, SwapBuffers=4844310487801, FrameCompleted=4844314195614, DequeueBufferDuration=296000, QueueBufferDuration=606000,
06-26 13:48:31.848 I/ViewRootImpl(21747): jank_removeInvalidNode jank list is null
[0:]
resetSolarSystem
[0:]
Need to cancel the running task
[0:]
Long running operation starts
06-26 13:48:33.207 D/Mono (21747): DllImport searching in: '__Internal' ('(null)').
06-26 13:48:33.207 D/Mono (21747): Searching for 'java_interop_jnienv_call_long_method_a'.
06-26 13:48:33.207 D/Mono (21747): Probing 'java_interop_jnienv_call_long_method_a'.
06-26 13:48:33.207 D/Mono (21747): Found as 'java_interop_jnienv_call_long_method_a'.
06-26 13:48:33.515 I/ViewRootImpl(21747): jank_removeInvalidNode jank list is null
[0:]
Long running operation is finished
[0:]
Long running operation is finished
[0:] ms 3597,4734
[0:] ms 1094,6135

Best Answer

Answers

  • jddjdd USMember ✭✭✭

    No! nowhere!
    I thought .NET was magical and did stop any thread when the CancellationTokenSource was cancelled :-°
    I undestand I need to pass the CancellationTokenSource to the long-running operation and check time to time the IsCancellationRequested to stop the operation if needed...

  • JohnHardmanJohnHardman GBUniversity mod

    @jdd said:
    No! nowhere!
    I thought .NET was magical and did stop any thread when the CancellationTokenSource was cancelled :-°

    If only :-)

    @jdd said:
    I undestand I need to pass the CancellationTokenSource to the long-running operation and check time to time the IsCancellationRequested to stop the operation if needed...

    Exactly.

Sign In or Register to comment.