Reyn
Reyn

Reputation: 757

Is Looping inside a Task Recommended?

Is Looping inside a task really recommended?

example code:

public void doTask(){
    Task.Factory.StartNew(() => {
        do{
           // do tasks here.... call webservice
        }while(true till cancelled)
    });
}

any answers would be great! :) because it is a case for my webservice calling right now, and the memory consumption goes out of control.

So may I ask, is looping inside a task really good or not recommended at all?

As Requested by SLC, heres the code:

CancellationTokenSource tokenSrc;
Task myTask;
private void btnStart_Click(object sender, EventArgs e)
{
    isPressed = !isPressed;



    if(isPressed)
    {
        tokenSrc = new CancellationTokenSource();
        myTask = Task.Factory.StartNew(() => 
        {
            do{
                checkMatches(tokenSrc.Token);
            }while(tokenSrc.IsCancellationRequested != true);
        }, tokenSrc.Token);
    }
    else {
        try{
            tokenSrc.Cancel();
            // Log to notepad
        }
        catch(Exception err){
           // Log to notepad
        }
        finally {
           if(myTask.IsCanceled || myTask.IsCompleted || myTask.isFaulted) {
               myTask.Dispose();
           }
        }

    }
}

private void checkMatches(CancellationTokenSource token) 
{
    try
    {
        if(!token.IsCancellationRequested)
        {
           //Create Endpoint...
           //Bypass ServCertValidation for test purposes
           ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate {return true;});
           using(WebServiceAsmx.SoapClient client = new....)
           {
               client.CheckResp response = client.chkMatch();
               // if's here for the response then put to logs
           }
        }
    }
    catch(Exception err)
    {
        // err.toLogs
    }
}

Upvotes: 1

Views: 81

Answers (1)

NibblyPig
NibblyPig

Reputation: 52952

It's perfectly fine to do this, especially if your task runs constantly, for example picking up a message queue.

while (not shutting down)
   get next email to send
   if exists next email to send
      send
   else
      wait for 10 seconds
wend

Ensure that you have a way to get out if you need to cancel it, like you've done with a flag, and you should be fine.

Regarding webservices:

You should have no problem calling the webservice repeatedly, nor should it cause any memory spikes. However, you should make sure your initialisation code is not inside the loop:

BAD

while (notShuttingDown)
   make a new connection
   initialise
   make a call to the service()
wend

GOOD

make a new connection
initialise
while (notShuttingDown)
    make a call to the service
wend

Depending on your webservice it might be more optimal to create a batch operation, for example if your service is HTTP then hitting it repeatedly involves a lot of overhead. A persistent TCP connection might be better because it could be creating and destroying a lot of objects to make the calls.

For example

slow, lots of overhead:

myRecords = { cat, dog, mouse }

foreach record in myRecords
    webservice check record
endforeach

faster:

myRecords = { cat, dog, mouse }
webservice check [myRecords] // array of records is passed instead of one by one

Debugging: The most likely risk is that somehow the task is not being disposed correctly - can you add this to your method to debug?

myTask = Task.Factory.StartNew(() => 
        {
            Console.Writeline("Task Started");
            do{
                checkMatches(tokenSrc.Token);
                Thread.Sleep(10); // Some pause to stop your code from going as fast as it possibly can and putting your CPU usage to 100% (or 100/number of cores%)
            }while(tokenSrc.IsCancellationRequested != true);
            Console.Writeline("Task Stopped");
        }

You might have to change that so it writes to a file or similar depending on if you have a console.

Then run it and make sure that only 1 task is being created.

Upvotes: 1

Related Questions