如何判断失败的方法调用参数值

本文关键字:方法 调用 参数 失败 何判断 判断 | 更新日期: 2023-09-27 18:12:58

我有一个包含大约30个条目的List<Task<searchDataResponse>>。在调试此列表时,我无法确定30个条目中哪一个是特定条目。

如何确定任务集合中特定任务的方法调用(包括输入参数值)?

示例代码:

var tasks = new List<Task<searchDataResponse>>();
for (var i = 0; i < 30; i++)
{
    // GET DATE OF N DAYS PAST (UP TO 30)
    var searchDate = DateTime.Now.AddDays(i * -1);
    // CALL WEB SERVICE WITH A SPECIFIC DATE
    var dateSpecificTask = wsClient.searchDataAsync(searchDate);
    // ADD TASK TO LIST OF TASKS
    tasks.Add(dateSpecificTask);
}
try
{
    Task.WaitAll(tasks.ToArray());
}
catch (AggregateException ae)
{
    // SET ALL EXCEPTIONS AS HANDLED
    ae.Handle(x => { return true; }); 
}
// GET LIST OF FAILED TASKS
var failedTasks = tasks.Where(x => x.Status == TaskStatus.Faulted).ToList();
// IDENTIFY FAILED TASKS - TRY TO IDENTIFY WHICH DATE SUPPLIED TO WEB SERVICE FAILED.
foreach (var failedTask in failedTasks)
{
    var failedMethod = failedTask.MethodSignature;   //<----  here is what i want to do.  Property 'MethodSignature' does not exist - this is merely an example of what I am attempting to do.
}

更新——一些评论表明,人们对"方法签名"这个短语的使用感到心痛。我所说的方法签名实际上是包括输入参数值的方法签名。因此,我改变了问题的标题,以更准确地反映我所寻求的。我的例子既做作又简单。这并不能反映我的现实问题。但我的问题仍然存在——在查看失败任务列表时,我如何确定作为任务一部分调用的实际方法。我似乎找不到任何描述导致失败的方法的任务属性

如何判断失败的方法调用参数值

var operations = Enumerable.Range(0, 30)
 .Select(i => {
     // GET DATE OF N DAYS PAST (UP TO 30)
    var searchDate = DateTime.Now.AddDays(i * -1);
    // CALL WEB SERVICE WITH A SPECIFIC DATE
    var dateSpecificTask = wsClient.searchDataAsync(searchDate);
    return new { i, searchDate, dateSpecificTask };
}.ToList();
Task.WaitAll(operations.ConvertAll(x => x.dateSpecificTask));
var failed = operation.Where(x => x.dateSpecificTask.State == Faulted).ToList();

failed列表中,您现在拥有所有日期和索引。

在你发布的代码中,我发现了一些差异,在我看来,这是源于Async-Await的使用没有得到很好的理解这一事实,让我在提出替代解决方案之前提出几个重要方面:

wsClient.searchDataAsync(searchDate)的调用不是awaited,这违背了Async调用的目的,因为这将使其成为阻塞的Synchronous调用,尽管您在Task List中聚集了所有Async调用以稍后等待,但这仍然是阻塞的,并且不会释放调用线程

代码修改:

  1. await wsClient.searchDataAsync异步调用,这肯定需要成为async方法的一部分

    for (var i = 0; i < 30; i++)
    {
      // GET DATE OF N DAYS PAST (UP TO 30)
        var searchDate = DateTime.Now.AddDays(i * -1);
     // CALL WEB SERVICE WITH A SPECIFIC DATE
      var dateSpecificTask = await wsClient.searchDataAsync(searchDate);
    // ADD TASK TO LIST OF TASKS
      tasks.Add(dateSpecificTask);
    }
    
  2. 等待任务集合Task.WhenAll而不是WaitAll,因为除了控制台应用程序没有Ui上下文,WaitAll的范围为死锁

修改代码如下:

return await Task.WhenAll(tasks)返回值将是Task<searchDataResponse[]>,因为所有调用都有相同的返回类型searchDataResponse

  • 现在你的问题的关键,如何让失败的任务,尽管在接受在上面的问题中,你可以创建一个包装器包含任务和其他值,因此地图,但是为什么不添加所有相关细节searchDataResponse返回类型,其模式还没有发布,是故障状态可以添加和更新在同一个然后从返回的Task<searchDataResponse[]> Async方法和所有你需要的是:
  • 打开结果Task<searchDataResponse[]>,获得searchDataResponse[],您可以获得所有失败/通过的详细信息。

    打开一个ASP文件有多种方法。Net项目:

    • 生成完整的调用链Async,它将自动展开最后在最顶端调用者中展开的结果

    对于控制台应用程序,使用如下命令:

    searchDataResponse [] results = Task.WhenAll(<returned searchDataResponse taskList>).ConfigureAwait(false).GetAwaiter().GetResult();
    

    如果您希望能够将日期传递给失败的任务,则可以将日期和任务存储在集合中(而不是像现在这样仅存储任务)。

    为什么不使用中间类,例如两个成员(date, task) ?