方法参数传递失效原因排查?附Dapper相关代码求助
问题排查与修复方案
核心问题:参数未传递到SiteResponse对象
你在CheckSite方法中接收了Url、Name、Websiteid参数,但创建SiteResponse实例后,没有将这些参数赋值给实例的对应属性。这导致后续RecordToDb方法中使用response.Name、response.Websiteid等字段时都是默认值(空字符串、0),看起来像是参数没传递过去。
修复代码:
public SiteResponse CheckSite(string Url, string Name, int Websiteid) { // 初始化时直接赋值参数到SiteResponse var result = new SiteResponse { Websiteid = Websiteid, Name = Name, Url = Url }; // 后续原有逻辑不变 }
其他潜在问题与优化
同步阻塞调用引发死锁风险
CheckSite中使用client.GetAsync(Url).Result是同步阻塞调用,在异步上下文(如GetAllWebsites是async方法)中容易引发死锁,且降低性能。建议改为异步实现:public async Task<SiteResponse> CheckSite(string Url, string Name, int Websiteid) { var result = new SiteResponse { Websiteid = Websiteid, Name = Name, Url = Url }; var stopwatch = new Stopwatch(); stopwatch.Start(); // 使用using自动释放HttpClient资源,或在构造函数复用单例HttpClient using var client = new HttpClient(); _logger.LogInformation($"TEST URL: {result.Url}"); try { // 用await替代.Result避免阻塞 var checkingResponse = await client.GetAsync(Url); result.Status = checkingResponse.IsSuccessStatusCode && checkingResponse.StatusCode == HttpStatusCode.OK; } catch { result.Status = false; } stopwatch.Stop(); result.ResponseTime = stopwatch.ElapsedMilliseconds; if (result.Status) { // 异步调用RecordToDb await RecordToDb(result); } else { _logger.LogInformation($"Status is {result.Status}"); } return result; }async void方法的异常风险RecordToDb使用async void会导致无法等待方法完成、无法捕获异步异常,建议改为async Task:public async Task RecordToDb(SiteResponse response) { var newRecord = new UptimeModel { Time = DateTime.Now, Status = response.Status, ResponseTime = (int)response.ResponseTime, Websiteid = response.Websiteid, Name = response.Name, }; _logger.LogInformation($"Trying to Save {response.Name}"); await _db.InsertUptime(newRecord); }异步方法未等待导致逻辑中断
修改GetAllWebsites,调用异步的CheckSite时必须用await,否则方法可能提前结束,导致后续逻辑未执行:public async Task GetAllWebsites() { var websites = await _webdb.GetWebsites(); // 并行处理提升效率(可选) var tasks = websites.Select(async website => { _logger.LogInformation($"WEBSITE::::: {website.Url} | {website.Name} | {website.Websiteid}"); await CheckSite(website.Url, website.Name, website.Websiteid); }); await Task.WhenAll(tasks); // 若需串行处理,替换为foreach+await // foreach (var website in websites) // { // _logger.LogInformation($"WEBSITE::::: {website.Url} | {website.Name} | {website.Websiteid}"); // await CheckSite(website.Url, website.Name, website.Websiteid); // } }HttpClient复用优化
每次创建HttpClient会消耗socket资源,建议在构造函数注入复用单例:private readonly HttpClient _httpClient; public UptimeService(IWebsiteData webdb, IUptimeData db, ILogger<UptimeService> logger, HttpClient httpClient) { _webdb = webdb; _logger = logger; _db = db; _httpClient = httpClient; }
内容的提问来源于stack exchange,提问作者Rahbit
相关产品推荐
相关产品推荐

