【问题标题】:Label.Text change being blocked?Label.Text 更改被阻止?
【发布时间】:2009-06-17 21:03:35
【问题描述】:

我正在尝试使用 Microsoft.SqlServer.Management.Smo.Restore 对象来恢复 SQL Server 2000 数据库。就在我开始恢复操作之前,我更改了标签的文本,以便用户知道发生了什么。但是,更改后的文本在 GUI 上不可见(即文本保持原样),直到在 fullRestore.Wait() 行之后。

lblStatus.Text = "Restoring Database";
Restore fullRestore = new Restore(); 

// Configure fullRestore

fullRestore.SqlRestore(_server);
fullRestore.Wait();

奇怪的是,lblStatus 最终确实显示“正在恢复数据库”,但直到 恢复完成后才显示。有什么想法吗?

【问题讨论】:

    标签: c# .net sql-server-2000 label database-restore


    【解决方案1】:

    您正在阻止 GUI 线程,这会阻止它更新。您可以调用 lblStatus.Refresh(),或将您的 Wait 移至后台线程(这最终是正确的做法)。

    【讨论】:

    • 调用 lblStatus.Refresh() 不会有任何区别,所做的只是使控件无效,因此它将被重新绘制,在 GUI 线程可用之前,实际的重新绘制仍然无法发生。
    • @Simon - 它在锁定 GUI 线程的调用之前重绘。
    • 有趣,我刚刚尝试了 lblStatus.Refresh() ,它完全符合我的需要。我知道 Wait() 的后台线程会是一个更好的解决方案,但这很简单并且现在可以工作。
    • 乔恩是对的;这就是 Control.Invalidate() 和 Control.Refresh() 之间的区别; refresh 首先调用 Invalidate,然后强制更新。
    • 嗯。这很有趣。我很高兴承认我显然完全错了。我原以为代码实际上是在前台线程上运行的,所以不会有更新发生的时刻。我认为 Fredrik 是对的,我没有意识到 refresh 实际上执行更新。我的错。
    【解决方案2】:

    这是一个线程问题。您可以在单独的线程或后台线程上执行此操作。我见过人们使用的一种方法是做一个 Application.DoEvents() 虽然我通常远离那个电话。

    【讨论】:

      【解决方案3】:

      在您完成前台线程的处理并释放它之前,无法更新 GUI。您需要在后台线程上进行恢复以允许前台线程继续更新 GUI。考虑将恢复代码放在单独的方法中并使用ThreadPool.QueueUserWorkItem( ),并传递恢复方法。这将在线程池线程上触发您的恢复方法。

      如果您需要对线程和完成后的通知进行更多控制,您可以使用BackgroundWorker

      【讨论】:

        猜你喜欢
        • 2018-06-18
        • 1970-01-01
        • 1970-01-01
        • 2020-02-21
        • 2011-06-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多