在推荐的任务中循环吗?

时间:2015-08-04 10:20:19

标签: c# .net web-services loops task

是否真的推荐在任务中循环?

示例代码:

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

任何答案都会很棒! :) 因为我的网络服务现在正在调用,并且内存消耗失控。

我可以问一下,在任务中循环是否真的很好或根本不推荐?

正如SLC所要求的,以下是代码:

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
    }
}

1 个答案:

答案 0 :(得分:1)

这样做非常好,特别是如果你的任务不断运行,例如拿起一个消息队列。

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

如果您需要取消它,请确保您有办法离开,就像您使用旗帜一样,并且您应该没事。

关于webservices:

重复调用Web服务应该没有问题,也不应该导致任何内存峰值。但是,您应确保初始化代码不在循环内:

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

根据您的Web服务,创建批处理操作可能更为理想,例如,如果您的服务是HTTP,则重复访问它会产生大量开销。持久的TCP连接可能更好,因为它可能会创建并销毁大量对象来进行调用。

例如

慢,很多开销:

myRecords = { cat, dog, mouse }

foreach record in myRecords
    webservice check record
endforeach

更快:

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

调试:最可能的风险是某个任务没有正确处理 - 你可以将它添加到你的方法进行调试吗?

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");
        }

您可能需要更改它,以便根据您是否有控制台来写入文件或类似文件。

然后运行它并确保只创建了1个任务。