我有一个WinForms项目,它已经存在多年,并且已经通过异步事件处理程序进行了改进:
private async void dgvNewOrders_CellClick(object sender, DataGridViewCellEventArgs e)
这个方法内部是一个异步调用:
var projectTemplate = await GetProjectTemplateFile(companyId, sourceLang, targetLang);
当程序在普通分辨率屏幕上运行时,它按预期运行。但是,当在高DPI屏幕上运行时,窗口的尺寸以及所有子控件的尺寸在遇到内部异步调用后会跳到一半大小。就好像程序突然在兼容模式下运行或缩放已被禁用一样。
目前,为了调试问题,GetProjectTemplateFile方法只包含以下内容:
private async Task<ProjectTemplateFile> GetProjectTemplateFile(long companyId, string sourceLanguage, string targetLanguage)
{
return null;
}
无论函数
GetProjectTemplateFile
是否进行异步操作都没有影响。如果我注释掉对
GetProjectTemplateFile
的异步调用,那么程序会按预期运行,即使在CellClick
事件中仍然有其他异步调用。我尝试给异步调用附加
.ConfigureAwait(true)
,但是并没有任何影响。同样,使用.GetAwaiter().GetResult()
同步运行该调用也没有影响。有人能解释一下为什么这个特定的异步调用会改变窗口的尺寸,或者如何防止发生这种情况吗?
更新: 根据要求,以下是一个引发上述行为的代码示例。我没有看到任何异常的情况,但我向您保证,正是这段代码引起了上述行为。
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
}
可能相关的其他信息:
- 窗口的
FormBorderStyle
是“FixedToolWindow” - 在启动方法中为窗口指定了明确的宽度
AutoSize
= FalseAutoSizeMode
= GrowOnly- 正在开发的计算机没有安装 Windows 10 1703(创作者更新),该更新具有新的缩放逻辑
- 如果
GetprojectTemplateFile
方法不是异步的,即方法签名为public ProjectTemplateFile GetProjecttemplateFile(...)
,则没有问题。此问题似乎仅在方法调用为异步时存在-即使我将其设置为阻止调用。
更新2:
我找到了导致此问题的特定代码行:
MessageBox.Show(...);
内部异步调用
GetProjectTemplateFile
调用API,并检查响应:var responseMessage = await client.GetAsync(uri);
if (!responseMessage.IsSuccessStatusCode)
{
MessageBox.Show(...);
return null;
}
如果我将
MessageBox.Show(...)
调用注释掉,那么一切正常,没有缩放问题,也没有尺寸跳动的情况。但是,当
MessageBox.Show(...)
调用被放置时,问题就会出现。此外,API响应200(OK),因此甚至没有使用MessageBox代码。我猜测JIT编译器认为这是可能的,所以......它重新渲染了表格?
同时,重要的是,这段代码不在表单的代码后台中,而是在一个类中,在构造函数中给表单一个实例。