【发布时间】:2021-05-07 13:56:49
【问题描述】:
我有一个 Winforms 程序,我在其中异步地从数据库中检索一些数据,并将其显示在 UI 上。这是我用来在标签上显示User & Scan iinformation 的函数:
private async Task PopulateLastScanAsync()
{
var scan = await Access.GetLastScanAsync(); // retrieve User/Scan data from database
if (scan.Item4) // Ignore this stuff
{
var result = await Access.GetUserAsync(scan.Item1.UserCode);
if (result.Item2)
{
// Display logic is here
User usr = result.Item1; // Display on UI
LastScannedName.Text = $"{usr.FirstName} {usr.LastName}";
LastScannedUserId.Text = $"{usr.UserCode}";
LastScanTime.Text = scan.Item1.ScanTime.ToString("g");
LastScanImage.Image = Manager.ConvertBytesToImage(usr.Picture);
// Read following comments after going thru the problem
// If here, I debug, like Console.WriteLine(LastScannedName.Text), it displays correct results on console, but incorrect text on UI. [During Timer_Tick event]
}
}
}
我在Form_Load事件中调用了这个方法,这个事件只是在UI上显示最后扫描的信息,效果很好:
private async void UC_Dashboard_Load(object sender, EventArgs e)
{
await PopulateLastScanAsync();
timerRefresher.Start();
}
我有一个计时器timerRefresher,每隔几秒就会计时一次,它的目的是刷新 UI 上显示的数据。它的tick事件中的代码是:
private async void timerRefresher_Tick(object sender, EventArgs e)
{
await PopulateLastScanAsync();
}
问题是:表单加载时数据在 UI 上正确显示,但 ticks 事件没有刷新标签上的更新值。
我知道这个问题来自async 的东西,但不知道如何摆脱它。
我试过的:
- Label.Update();
- Label.Refresh();
- Label.Invoke();
- Label.Invalidate();
// And some other stuff answered in other similar questions
以及Label控件自带的其他方法。
谢谢。
【问题讨论】:
-
如果您删除
await Task.Delay(100);并在处理程序中只保留LastScannedName.Text += "*";,那么标签是否会更新?请在不附加调试器的情况下尝试。使用 Ctrl+F5 从 Visual Studio 启动程序。 -
我对值是相同还是不同不感兴趣。如果标签在每个
Tick上更新,或者永远保持其初始值,我很感兴趣。关于连接你的电脑,我做不到,抱歉。 -
标签在初始值上保持冻结状态。我已经公开了
timerRefresher访问权限,并以不同的形式启动了timerRefresher。我只是尝试从相同的表格开始,它现在可以工作了。感谢您的宝贵时间。 -
您在哪里展示这些控件 (
LastScannedName& Co.)? -- 添加签入PopulateLastScanAsync():bool hasHandle = LastScannedName.IsHandleCreated;。如果hasHandle是false,那么var handle = LastScannedName.Handle等等。看看这是否使控件更新。删除所有那些.Refresh()、.Update()等。另外,打印到控制台Thread.CurrentThread.ManagedThreadId,看看那是什么。除非你在说什么,否则 async/await 在 U 线程中恢复。 -
"并且正在从不同的表单启动 timerRefresher。"您的问题很可能是参考问题,您正在创建第一个表单的实例并认为这将允许您更改屏幕上已经存在的现有表单...
标签: c# winforms user-interface asynchronous async-await