C# - Task.WaitAll()不等待所有任务完成

时间:2016-02-04 23:10:55

标签: c# multithreading task-parallel-library task

我正在使用C#代码将Xml发送到api端点并捕获响应 我这样做的方式如下 我有100 xmls的文件夹A,100 Xmls的文件夹B和100 xmls的文件夹

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

文件夹任务循环遍历每个文件夹中的所有xml并捕获响应。这是在sendrequestandcaptureresponse()方法

中完成的

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

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

请找到以下代码

通过文件夹迭代的代码

foreach(Folder in Folders){

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

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

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

    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方法,但仍然无法等到所有任务完成。

任何帮助都会很棒。

提前致谢

在下面添加SendRequestAndCaptureResponse代码

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

}

1 个答案:

答案 0 :(得分:1)

你没有等待内部任务:

foreach(Folder in Folders){

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

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

因此,您的迭代不会等待内部任务结束 - 在每次迭代中,您只需创建一个任务并继续。

创建任务的更优雅方式是:

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

(错字不敏感)