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

本文关键字:等待 任务 Task WaitAll | 更新日期: 2023-09-27 18:33:27

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

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

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

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

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

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

你不等待内部任务:

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

(错别字不敏感(