c# - 在一定时间后取消 Task.WhenAll
问题描述
我有一个异步操作,它将航空公司列表作为参数并返回一些数据,并且我有一个航空公司列表,我想为其获取数据。
但是,如果在预定义的时间后我无法获得所有这些航空公司的数据,我想停止等待并将其他内容返回给用户。
public async Task Run()
{
var watch = System.Diagnostics.Stopwatch.StartNew();
await RunAirline();
watch.Stop();
Console.WriteLine($"Total Execution Time: {watch.ElapsedMilliseconds + Environment.NewLine}");
//return $"Total Execution Time: {watch.ElapsedMilliseconds + Environment.NewLine}";
//Console.ReadLine();
}
private static async Task RunAirline()
{
try
{
List<string> AirlineList = GetAirLineCodes();
List<Task<WebsiteDataModel.WebsiteDataModel>> taskList = new List<Task<WebsiteDataModel.WebsiteDataModel>>();
foreach (string AirlineCode in AirlineList)
{
taskList.Add(Task.Run(() => CallindividualAirline(AirlineCode)));
}
var result = await Task.WhenAll(taskList);
foreach (WebsiteDataModel.WebsiteDataModel model in result)
{
Display(model);
}
}
catch (Exception Ex)
{
Console.WriteLine(Ex.Message.ToString());
}
}
private static List<string> GetAirLineCodes()
{
return new List<string>()
{
"A",
"B",
"C"
};
}
private static void Display(WebsiteDataModel.WebsiteDataModel result)
{
Console.WriteLine($"Website Content as {result.DataContent} , Website Name as : {result.WebsiteName} Status as : {result.Status} , Content length as : {result.WebsiteData.Length} ----- Error as : {result.error.FaultException.ToString()}." + Environment.NewLine);
}
private static WebsiteDataModel.WebsiteDataModel CallindividualAirline(string AirlineCode)
{
WebsiteDataModel.WebsiteDataModel LobjWebsiteDataModel = new WebsiteDataModel.WebsiteDataModel();
WebsiteDataModel.ErrorData LobjErrorData = new WebsiteDataModel.ErrorData();
try
{
switch (AirlineCode)
{
// calling Airline API...........
case "A":
ClsAirOne LobjAirOne = new ClsAirOne();
LobjWebsiteDataModel = LobjAirOne.GetAirDataData("https://book.xxxxx.com");
return LobjWebsiteDataModel;
case "B":
ClsAirTwo LobjAirTwo = new ClsAirTwo();
LobjWebsiteDataModel = LobjAirTwo.GetAirData("https://book.xxxxx.in");
return LobjWebsiteDataModel;
case "C":
ClsAirThree LobjAirThree = new ClsAirThree();
LobjWebsiteDataModel = LobjAirThree.GetAirData("https://xxxxx.in/");
return LobjWebsiteDataModel;
default:
return LobjWebsiteDataModel;
}
}
catch (Exception Ex)
{
LobjWebsiteDataModel.Status = "0";
LobjWebsiteDataModel.WebsiteData = "";
LobjErrorData.FaultException = "ERR-01" + Ex.Message.ToString();
LobjWebsiteDataModel.error = LobjErrorData;
return LobjWebsiteDataModel;
}
}
解决方案
最好的方法是取消传递给Task.WhenAll
. 您可以创建一个带有超时的取消令牌源,然后将其传递CancellationToken
给实际执行 I/O 的方法。
例如:
public async Task Run()
{
...
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
await RunAirline(cts.Token);
...
}
private static async Task RunAirline(CancellationToken cancellationToken)
{
...
foreach (string AirlineCode in AirlineList)
taskList.Add(Task.Run(() => CallindividualAirline(AirlineCode, cancellationToken)));
...
}
private static WebsiteDataModel.WebsiteDataModel CallindividualAirline(string AirlineCode, CancellationToken cancellationToken)
{
...
ClsAirOne LobjAirOne = new ClsAirOne();
LobjWebsiteDataModel = LobjAirOne.GetAirDataData("https://book.xxxxx.com", cancellationToken);
...
ClsAirTwo LobjAirTwo = new ClsAirTwo();
LobjWebsiteDataModel = LobjAirTwo.GetAirData("https://book.xxxxx.in", cancellationToken);
...
}
推荐阅读
- javascript - 对 iQuery 方法 .css() 使用多个值会引发错误:'missing )'。然而它并没有丢失
- javascript - 拖放在由 DOM 创建的项目上返回“null”
- c++ - “轻推”服务器以保持连接打开的简单方法?
- html - HTML5 输入模式属性 - 正则表达式失败
- python - 聚类后会发生什么
- css - 如何响应地将 CSS 网格模板列转换为行
- spring-boot - 与 Camunda 集成的 Spring Boot 独立应用程序可以使用来自 JbossFuse 的 JMS 消息吗?
- javascript - Jest/Enzyme - TypeError: div.find 不是函数
- java - 如何在 IntelliJ-IDEA 中自动构建?
- youtube - 如何在不使用搜索的情况下查找 youtube 频道当前是否正在直播?