是否真的推荐在任务中循环?
示例代码:
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
}
}
答案 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个任务。