Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# how cancel an executing method

I have a delegate method to run a heavy process in my app (I must use MS Framework 3.5):

private delegate void delRunJob(string strBox, string strJob);

Execution:

    private void run()
    {
        string strBox = "G4P";
        string strJob = "Test";

        delRunJob delegateRunJob = new delRunJob(runJobThread);
        delegateRunJob.Invoke(strBox, strJob);
    }

In some part of the method runJobThread

I call to an external program (SAP - Remote Function Calls) to retrieve data. The execution of that line can take 1-30 mins.

private void runJobThread(string strBox, string strJob)
{
    // CODE ...
    sapLocFunction.Call(); // When this line is running I cannot cancel the process
    // CODE ...
}

I want to allow the user cancel whole process.

How can achieve this? I tried some methods; but I fall in the same point; when this specific line is running I cannot stop the process.

like image 620
MiBol Avatar asked Mar 16 '23 19:03

MiBol


2 Answers

Instead of using the delegate mechanism you have to study the async and await mechanism. When you understand this mechanism you can move to cancellationtoken. An example doing both things can be found here : http://blogs.msdn.com/b/dotnet/archive/2012/06/06/async-in-4-5-enabling-progress-and-cancellation-in-async-apis.aspx

like image 63
Philip Stuyck Avatar answered Mar 18 '23 07:03

Philip Stuyck


Well; I find out a complicated, but effective, way to solve my problem:

a.) I created a "Helper application" to show a notification icon when the process is running (To ensure to don't interfere with the normal execution of the main app):

private void callHelper(bool blnClose = false)
{
    if (blnClose)
        fw.processKill("SDM Helper");
    else
        Process.Start(fw.appGetPath + "SDM Helper.exe");
}

b.) I created a Thread that call only the heavy process line.

c.) While the Thread is alive I check for external file named "cancel" (The "Helper application" do that; when the user click an option to cancel the process the Helper create the file).

d.) If exists the file; dispose all objects and break the while cycle.

e.) The method sapLocFunction.Call() will raise an exception but I expect errors.

private void runJobThread(string strBox, string strJob)
{
    // CODE ...

    Thread thrSapCall = new Thread(() =>
    {
        try { sapLocFunction.Call(); }
        catch { /* Do nothing */ }
    });

    thrSapCall.Start();

    while (thrSapCall.IsAlive)
    {
        Thread.Sleep(1000);
        try
        {
            if (fw.fileExists(fw.appGetPath + "\\cancel"))
            {
                sapLocFunction = null;
                sapLocTable = null;
                sapConn.Logoff();
                sapConn = null;
                canceled = true;
                break;
            }
        }
        finally { /* Do nothing */ }
    }

    thrSapCall = null;

    // CODE ...
}

Works like a charm!

like image 23
MiBol Avatar answered Mar 18 '23 07:03

MiBol