c# - WPF Thread dead lock
问题描述
may i find useful answer from you. I have WPF application fetching the data from API, I have thread deadlock when i fire following code
private List<Clinic> _clinics;
public List<Clinic> Clinics {
get { return _clinics; }
set { _clinics = value; OnPropertyChanged(); }
}
private Clinic _selectedClinic;
public Clinic SelectedClinic {
get { return _selectedClinic; }
set {
_selectedClinic = value; OnPropertyChanged();
if (value != null)
OnSelectClinic(value).Wait();
}
}
private async Task OnSelectClinic(Clinic clinic) {
try {
using (var request = await Client.GetAsync("URL OF API")) {
if (request.IsSuccessStatusCode){
StaffList = await request.Content.ReadAsAsync<Staff>();
}
var error = await request.Content.ReadAsStringAsync();
throw new Exception(error);
}
} catch (Exception e) {
Debug.WriteLine(e);
}
}
this is the view model, and Clinics, selectedClinic and Staff are binding to View.XAML
and here is the API Method
[HttpGet("FindAllByClinic/{clinicId}")]
public async Task<IActionResult> FindAllByClinic(int clinicId) {
try {
return Ok(_mapper.Map<List<Staff>>(await _staffRepository
.FindAllBy(clinicId)));
} catch (Exception e) {
return BadRequest(e.Message);
}
}
Here is StaffRepository method :
public async Task<ICollection<Staff>> FindAllBy(int clinicId, int medicalPointId) {
var persons = await Context.Persons.FromSql("EXEC HR.GetPersonsByClinicId @ClinicId = 0," +
$"@EncryptPassword = '{DecryptPassword}'").ToListAsync();
var staffs = await Context.Staff
.Include(e => e.StaffClinics)
.ThenInclude(e => e.Clinic)
.ThenInclude(e => e.ClinicMedicalPoints)
.Where(e => e.StaffClinics.Any(c => c.ClinicId == clinicId
&& c.Clinic.ClinicMedicalPoints.Any(m => m.MedicalPointId
== medicalPointId)))
.ToListAsync();
foreach (var staff in staffs) {
staff.Person = persons.FirstOrDefault(e => e.Id == staff.PersonId);
}
return staffs;
}
the problem is when i select a clinic from combobox the entire application freeze Can any one give me suggestions or correct my code if I Have mistakes please
解决方案
public Clinic SelectedClinic {
get { return _selectedClinic; }
set {
_selectedClinic = value; OnPropertyChanged();
if (value != null)
OnSelectClinic(value).Wait();
}
}
这个二传手非常糟糕,因为:
它引发了一个事件
OnPropertyChanged
- 没关系 - 但它继续在 setter 主体中执行昂贵的操作。您已经在发起一个事件,也许应该订阅它并执行它OnSelectClinic
?您正在阻塞
async
代码,这是导致死锁的罪过。通常解决方案是用await
s 替换阻塞等待,但在这种情况下,您需要重新设计,以便属性设置器不负责触发和等待此操作。
推荐阅读
- c# - 在 WebAPI DelegatingHandler 中未等待的异步任务中尝试/捕获未捕获错误
- python - pandas groupby 列并检查组是否满足多个条件
- python - 为独特的类实例 Python 制作装饰器的最佳方法
- kubernetes - 应该在什么公制编织网上发出警报?
- rust - 如何在并发请求之间共享 reqwest::Client?
- google-apps-script - ScriptApp.getService().getUrl() 指向开发 URL。我怎样才能让它指向 exec 生产 URL?
- sql - Mariadb 扫描时间戳列中的所有分区
- asp.net-core - 如何在 ASP.NET Core 3.1 中禁用 JSON OK 响应(但不是错误)
- python - 递增时间戳
- javascript - onClick 没有触发,事件是一个函数