I have a WinForms project that is already several years old and it was a retro-asynchronous event handler:
private async void dgvNewOrders_CellClick(object sender, DataGridViewCellEventArgs e)
Inside this method, an asynchronous call is used:
var projectTemplate = await GetProjectTemplateFile(companyId, sourceLang, targetLang);
When the program starts up on the screen with a normal resolution, it works as expected. However, when launched on a high DPI screen, the window sizes, as well as the sizes of all child controls, go to half the size as soon as it encounters this internal asynchronous call. It is as if the program suddenly started in compatibility mode or the scaling was turned off.
Currently, to debug a problem, the GetProjectTemplateFile method consists simply of
private async Task<ProjectTemplateFile> GetProjectTemplateFile(long companyId, string sourceLanguage, string targetLanguage) { return null; }
It does not matter whether GetProjectTemplateFile performs an asynchronous operation or not.
If I comment that the asynchronous call to GetProjectTemplateFile , then the program works as expected without any change in size, even if there are still other asynchronous calls made in the CellClick event.
I tried adding .ConfigureAwait(true) to an asynchronous call, which doesn't matter. Also, a synchronous call is not made with .GetAwaiter().GetResult() .
Can someone explain why window sizes are resized using this particular asynchronous call and / or how to prevent this?
Update
As per the request, here is a sample code that invokes the explained behavior. There is nothing unusual here that I can see, but I assure you that this code causes an explanation of the behavior.
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;
Some other information that may make a difference:
FormBorderStyle window - "FixedToolWindow"- Window gets explicit width in start method
AutoSize = FalseAutoSizeMode = GrowOnly- The computer on which it is being developed does not have Windows 10 1703 (Creator's), which has a new scaling logic
- If the
GetProjectTemplateFile method is not asynchronous, that is, it has the signature public ProjectTemplateFile GetProjecttemplateFile(...) , then there is no problem. This problem only exists when the method call is asynchronous, even if I make it a blocking call.
UPDATE 2:
I found specific lines of code that cause this problem:
MessageBox.Show(...);
An internal asynchronous call to GetProjectTemplateFile calls the API and then checks the response:
var responseMessage = await client.GetAsync(uri); if (!responseMessage.IsSuccessStatusCode) { MessageBox.Show(...); return null; }
If I comment on the call to MessageBox.Show(...) , then everything is fine, without scaling problems, without resizing.
But the problem occurs when the call to MessageBox.Show(...) is in place.
In addition, the API responds with 200 (OK), so the MessageBox code is not even used. I assume the JIT compiler sees this as an opportunity so ... does it re-render the form?
In addition, importantly, this code is not in the code-behind form, it is in the class to which the form is assigned an instance in its constructor.