无法将类型 'System.Collections.Generic.IEnumerable<System.Threading.Tasks.Task>' 隐式转换为 <System.Threading.Tasks.Task<bool>>'

Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<System.Threading.Tasks.Task>' to <System.Threading.Tasks.Task<bool>>'

None 的建议解决方案与我当前的问题相关。

这是我昨天的话题的延续:

在上面的线程中,我得到了应用程序来监控服务器和应用程序 运行 在他们的帮助下。

然而,事实证明有些服务器不允许 pinging。

为了解决这个问题,我尝试重写代码以监控 URL 而不是服务器。

现在,我有一些错误正在努力解决。

Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<System.Threading.Tasks.Task>' to 'System.Collections.Generic.IEnumerable<System.Threading.Tasks.Task<bool>>'. An explicit conversion exists (are you missing a cast?)

错误在第 22 行,也就是这一行:

IEnumerable < Task<bool> > tasks = args.Select(async url =>

知道我需要进行哪些更改才能解决此错误吗?

using System;
using System.IO;
using System.Net;
using System.Net.Mail;
using System.Net.NetworkInformation;
using System.Text;
using System.Configuration;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Net.Http;
using System.Linq;

namespace showserverstatus
{
    class Program
    {
        static async Task<int> Main(string[] args)
        {
            System.Collections.Concurrent.ConcurrentDictionary<string, string> urlToStatus = new();

            //IEnumerable<Task<bool>> tasks = (IEnumerable<Task<bool>>)args.Select(async url =>
            IEnumerable < Task<bool> > tasks = args.Select(async url =>
            {
                bool result = await ServerStatusByAsync(url);
                urlToStatus.TryAdd(url, result ? "UP" : "DOWN");
            });

            bool[] results = await Task.WhenAll(tasks);

            StringBuilder body = new("Please find the status of the servers below:");
            foreach (var kvp in urlToStatus)
            {
                body.AppendLine();
                body.AppendFormat("{0}: {1}", kvp.Key, kvp.Value);
            }

            await SendEmailAsync("Server Status", body.ToString());
            await Task.Delay(3000);

            // Return the number of servers which were down:
            return results.Count(result => !result);
        }
        static async Task<bool> ServerStatusByAsync(string url)
        {
            HttpClient http = new();
            using (HttpResponseMessage response = await http.GetAsync(url))
            {
                Console.WriteLine("GET {0}: {1}", url, response.StatusCode);

                if (response.IsSuccessStatusCode)
                {
                    await SendEmailAsync($"{url} WORKING", $"GET {url} returned {response.StatusCode}");
                    return true;
                }

                await SendEmailAsync($"{url} DOWN", $"GET {url} returned {response.StatusCode}");
                return false;
            }
        }

        static async Task SendEmailAsync(string subject, string body)
        {
            using MailMessage mm = new(ConfigurationManager.AppSettings["FromEmail"], "joeblow@gmail.com");
            mm.To.Add("joeblow@gmail.com");
            mm.CC.Add("janedoe@yahoo.com");
            mm.Subject = subject;
            mm.Body = body;
            mm.IsBodyHtml = false;

            SmtpClient smtp = new()
            {
                Host = ConfigurationManager.AppSettings["Host"],
                Port = int.Parse(ConfigurationManager.AppSettings["Port"]),
                EnableSsl = true,
                UseDefaultCredentials = false,
                Credentials = new NetworkCredential(ConfigurationManager.AppSettings["Username"], ConfigurationManager.AppSettings["Password"]),
            };

            await smtp.SendMailAsync(mm);
        }
    }
}

看看这个操作中发生了什么:

IEnumerable<Task<bool>> tasks = args.Select(async url =>
{
    bool result = await ServerStatusByAsync(url);
    urlToStatus.TryAdd(url, result ? "UP" : "DOWN");
});

该变量需要一个任务列表,而您确实返回了一个任务列表。 但是,它专门请求 Task<bool> 的列表,这将是一项解析为 bool 的任务。但是您提供的任务根本没有解决任何价值。

要么更改预期类型以匹配返回的内容:

IEnumerable<Task> tasks = args.Select(async url =>
{
    bool result = await ServerStatusByAsync(url);
    urlToStatus.TryAdd(url, result ? "UP" : "DOWN");
});

更改返回的内容以匹配预期类型:

IEnumerable<Task<bool>> tasks = args.Select(async url =>
{
    bool result = await ServerStatusByAsync(url);
    urlToStatus.TryAdd(url, result ? "UP" : "DOWN");
    return result;
    // or return whatever bool value you want to return
});

(请注意,我现在无法对此进行测试,这是来自直觉和文档)。 我认为您忘记了 lambda 中的 return,这导致了令人困惑的错误消息,因为类型已被删除,但编译器仍然设法大喊大叫。

我想这就是你想要的

IEnumerable <Task<bool>> tasks = args.Select(async url => { 
bool result = await ServerStatusByAsync(url);
return urlToStatus.TryAdd(url, result ? "UP" : "DOWN");
});