C#-Task.WaitAll()不等待所有任务完成 [英] C# - Task.WaitAll () is not waiting for all task to finish

查看:1246
本文介绍了C#-Task.WaitAll()不等待所有任务完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用C#代码将Xml发送到api端点并捕获响应 我的方法如下 我的文件夹A的XML值为100,文件夹B的XML为100,而文件夹C的XML为100.

I am using C# code to send an Xml to an api end point and capture the response The way I do it is as follows I have folder A with 100 xmls, folder B with 100 Xmls and folder C with 100 xmls

我遍历每个文件夹,并在每次循环迭代中创建一个任务.让我们将其称为文件夹任务

I loop through each of the folders and in each loop iteration I create a task. Lets call this as folder task

文件夹任务循环遍历每个文件夹中的所有xml,并捕获响应.这是通过sendrequestandcaptureresponse()方法完成的

The folder task loop through all the xml in each folder and captures the response. This is accomplished in sendrequestandcaptureresponse() method

我面临的问题是在处理所有xml之前的循环结束.对于所有300个XMLS(位于文件夹A,B和C中)都触发了sendrequestandcaptureresponse()方法,但是我仅获得了150个(大约)XMLS的响应

The issue I am facing is the loop end before all the xmls are processed. sendrequestandcaptureresponse() method is triggered for all the 300 XMLS ( which is in folder A, B and C ) but I get the response for only 150 (approximately) XMLS

Task.WaitAll(tasklist)在等待所有XML响应之前退出

Task.WaitAll(tasklist) exits before waiting for all XML responses

请在下面找到代码

要遍历文件夹的代码

foreach(Folder in Folders){

             Task t=Task.Factory.StartNew(
                async () =>
                            {                                
                                Httpmode.RunRegressionInHTTPMode(folderPath);                                         
                            }
                        }).Unwrap();                    
                tasklist.Add(t);

        }           
Task.WaitAll(tasklist.ToArray());


发送请求并捕获响应的代码


Code which sends request and captures response

    public void RunRegressionInHTTPMode(folderPath){


        try
        {
            string directoryPath = CurrServiceSetting.GetDirectoryPath();
            var filePaths = CreateBlockingCollection(folderPath+"\\Input\\");                
            int taskCount = Int32.Parse(CurrServiceSetting.GetThreadCount());

            var tasklist = new List<Task>();
            for (int i = 0; i < taskCount; i++)
            {   
                var t=Task.Factory.StartNew(
                          async  () =>
                            {
                            string fileName;
                            while (!filePaths.IsCompleted)
                            {  
                                 if (!filePaths.TryTake(out fileName)) 
                                    {                                     
                                        continue;
                                    }

                                 try{   
                                    SendRequestAndCaptureResponse(fileName,CurrServiceSetting,CurrSQASettings,testreportlocationpath);                                        
                                 }
                                 catch(Exception r)
                                 {
                                    Console.WriteLine("#####SOME Exception in SendRequestAndCaptureResponse "+r.Message.ToString());                                        
                                 }
                            }
                        }).Unwrap();
                tasklist.Add(t);
             }                
            Task.WaitAll(tasklist.ToArray());                   
        }
        catch(Exception e)
        {

        }
    }

任何人都可以指出我在这里缺少的内容.我将任务设置为异步任务,并在任务结束时添加了Unwrap方法,但仍然无法等待所有任务完成.

Could anyone please point me what I am missing here. I made the task as async task and added Unwrap method at the end of the task but still not able to wait till all the task are finished.

任何帮助都会很棒.

预先感谢

在下面添加SendRequestAndCaptureResponse代码

Adding the SendRequestAndCaptureResponse code below

public void  SendRequestAndCaptureResponse(string fileName,ServiceSettings curServiceSettings,SQASettings CurrSQASettings,string testreportlocationpath){            
        XmlDocument inputxmldoc = new XmlDocument ( );               

        Stream requestStream=null;
        byte[] bytes;
        DateTime requestsenttime=DateTime.Now;
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create ( url );
        string responseStr = "";

        bytes = Encoding.ASCII.GetBytes ( str4 );
        try{ 
            request.ContentType = "text/xml; encoding='utf-8'";
            request.ContentLength = bytes.Length;
            Credentials credentials = new Credentials();        
            request.Credentials = new NetworkCredential (CurrSQASettings.GetUserName(), CurrSQASettings.GetPassword());
            request.Method = "POST";
            request.Timeout = Int32.Parse(curServiceSettings.GetTimeOut());
            //OVERRIDING TIME
            requestsenttime=DateTime.Now;
            requestStream = request.GetRequestStream ( );        
            requestStream.Write ( bytes, 0, bytes.Length );         
            requestStream.Close ( );
         }
         catch(Exception e){
            return;
         }



        HttpWebResponse response;
        try
        {
        response = (HttpWebResponse)request.GetResponse ( );
        if (response.StatusCode == HttpStatusCode.OK)
        {        


        allgood = true;
        Stream responseStream = response.GetResponseStream ( );
        responseStr = new StreamReader ( responseStream ).ReadToEnd ( );
        XmlDocument xml = new XmlDocument ( );
        xml.LoadXml ( responseStr );     
        xml.Save(resultantactualxmlpath);        
        response.Close();
        responseStream.Close();           

        }

        }
        catch(Exception  e){
            return;
        }

}

推荐答案

您不必等待内部任务:

foreach(Folder in Folders){

             Task t=Task.Factory.StartNew(
                async () =>
                            {                                
                                await Httpmode.RunRegressionInHTTPMode(folderPath);  // <--- await here                                         
                            }
                        }).Unwrap();                    
                tasklist.Add(t);

        }           
Task.WaitAll(tasklist.ToArray());

因此,您的迭代无需等待内部任务结束-在每次迭代中,您只需创建一个Task并继续进行即可.

Therefor, your iterations doesn't wait for the inner Tasks to end - in each iteration you just create a Task and moves on.

创建任务的一种更优雅的方法是:

A more elegant way to create the Tasks would be:

var tasks = Folders.Select(p=> Httpmode.RunRegressionInHTTPMode(p)).ToArray();
Task.WaitAll(tasks);

(对打字错误不敏感)

这篇关于C#-Task.WaitAll()不等待所有任务完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆