Mam projektu WinForm, który ma już kilka lat i został retro wyposażony asynchronicznych Event-ładowarki:okno WinForms zmienia wymiarów po napotkaniu połączenia asynchronicznego
private async void dgvNewOrders_CellClick(object sender, DataGridViewCellEventArgs e)
Wewnątrz tej metody jest wywołanie asynchroniczne:
var projectTemplate = await GetProjectTemplateFile(companyId, sourceLang, targetLang);
Gdy program działa na ekranie o normalnej rozdzielczości, działa zgodnie z oczekiwaniami. Jednak po uruchomieniu na ekranie o wysokiej czułości, wymiary okna - jak również wszystkie kontrolki podrzędne - przeskakują do połowy rozmiaru zaraz po napotkaniu tego wewnętrznego połączenia asynchronicznego. To tak, jakby program nagle uruchomił się w trybie zgodności lub skalowanie zostało wyłączone.
Obecnie, w celu debugowania problemu, metoda GetProjectTemplateFile
składa się po prostu z
private async Task<ProjectTemplateFile> GetProjectTemplateFile(long companyId, string sourceLanguage, string targetLanguage)
{
return null;
}
Nie ma znaczenia, czy GetProjectTemplateFile
wykonuje operację asynchronicznej lub nie.
Jeśli skomentuję to połączenie asynchroniczne z GetProjectTemplateFile
, program będzie działał zgodnie z oczekiwaniami bez żadnego przeskoku wymiarów, mimo że w przypadku zdarzenia CellClick
są jeszcze inne wywołania asynchroniczne.
Próbowałem dołączyć .ConfigureAwait(true)
do wywołania asynchronicznego, co nie ma znaczenia. Połączenia nie można też synchronicznie synchronizować z .GetAwaiter().GetResult()
.
Czy ktoś może wyjaśnić, dlaczego wymiary okna zmieniają się za pomocą tego konkretnego połączenia asynchronicznego i/lub jak temu zapobiec?
Aktualizacja
Zgodnie z prośbą, oto przykładowy kod, który wywołuje wytłumaczyć zachowanie. Nie dzieje się tutaj nic niezwykłego, ale mogę zapewnić, że ten kodeks powoduje wyjaśnione zachowanie.
private async void dgvNewOrders_CellClick(object sender, DataGridViewCellEventArgs e)
{
var result = await _templateInteraction.GetProjectTemplateFile(1,
"en-US",
"de-CH");
return;
}
public class TemplateInteraction : ITemplateInteraction
{
public async Task<ProjectTemplateFile> GetProjectTemplateFile(long companyId, string sourceLanguage, string targetLanguage)
{
return null;
// elided code
}
// other methods
}
Niektóre inne informacje, które mogą być istotne:
FormBorderStyle
okna jest "FixedToolWindow"- Okno jest podane wyraźne szerokość w sposobie uruchamiania
AutoSize
= falseAutoSizeMode
= Wzrost tylko- The Komputer którym jest rozwijany na nie posiada Windows 10 1703 (Stwórcy) aktualizację, która ma nowa logika skalowanie
- Jeśli metoda
GetprojectTemplateFile
jest nie asynchroniczny, tj ma podpispublic ProjectTemplateFile GetProjecttemplateFile(...)
wtedy nie ma problemu. Ten problem wydaje się istnieć tylko wtedy, gdy wywołanie metody jest asynchroniczne - nawet jeśli wywołam blokowanie.
UPDATE 2:
znalazłem konkretnej pozycji (-y) kodu, które powodują ten problem:
MessageBox.Show(...);
Wewnętrzna połączenia asynchronicznego, GetProjectTemplateFile
, wywołuje API i sprawdza odpowiedź:
var responseMessage = await client.GetAsync(uri);
if (!responseMessage.IsSuccessStatusCode)
{
MessageBox.Show(...);
return null;
}
Jeśli komentarz out połączenia MessageBox.Show(...)
wtedy wszystko jest normalne, bez skalowania proble ms, bez skoków w wymiarach.
Ale problem występuje, gdy wywołanie MessageBox.Show(...)
jest na miejscu.
Co więcej, API odpowiada 200 (OK), więc kod MessageBox nie jest nawet używany. Zgaduję, że kompilator JIT widzi to jako możliwość, więc ... ponownie renderuje formularz?
Co ważne, ten kod nie znajduje się w zadeklarowanym kodzie formularza, jest w klasie, której formularz jest podany w swoim konstruktorze.
Proszę zaksięgować kompletną i minimalną próbkę, która odtworzy zachowanie, które widzisz. Uwzględnij wszystko, co może być istotne, jakiego framework używasz, os itd. Jeśli 'asynchroniczne' jest naprawdę losowo zmieniające rozmiar formularza, to byłoby to interesujące dla ciebie, aby dowiedzieć się co najmniej. – JSteward
Dziękuję za aktualizację, ale nie mogę odtworzyć tego, co widzisz. Oto kod, którego używam: [dotnet Fiddle] (https://dotnetfiddle.net/6Sn4cj) – JSteward
Nawet z .NET 4.6? – awj