如何使表单延迟显示 [英] how to make form delay a display

查看:23
本文介绍了如何使表单延迟显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Application.DoEvents();这做到了.在这里找到:从 UI 线程强制更新 GUI

edit: Application.DoEvents(); this did it. found here: Force GUI update from UI Thread

c#,winforms.我想以 1 为步长增加一个数字,并将这些增量显示在列表视图中,以便用户看到数字递增(例如从 10 到 15).

c#, winforms. i want to increase a number by steps of 1 and have those increments shown inside a listview, so that the user sees the number counting up (for example from 10 to 15).

我有另一个按钮,单击时仅增加 1 并使用相同的 display().它工作正常并按预期更新显示.

i have another button that increments just by 1 when clicked and uses the same display(). it works fine and updates the display as expected.

我尝试了这些代码(缩短以节省空间):

i tried these codes (shortened to save space here):

(1)

for (int i = 0; i < 5; i++) 
{
    var t = Task.Run (async () =>
    {
        myInt++;
        await Task.Delay(300);
        display(); //forces screen refresh
    });
}

(2)

for (int i = 0; i < 5; i++) 
{
    var t = Task.Run (() =>
    {
        myInt++;
        Task.Delay(300).Wait;
        display();
    });
    //t.Wait(); //causes "An unhandled exception of type 'System.AggregateException' occurred in mscorlib.dll"
}

(3)

for (int i = 0; i < 5; i++) 
{
    myInt++;
    display();
    System.Threading.Thread.Sleep(300);
}

(4)

Stopwatch stopwatch = new Stopwatch();
for (int i = 0; i < 5; i++) 
{
    stopwatch.Restart();
    while (true)
    {
        if (stopwatch.ElapsedMilliseconds >= 300)
        {
            break;
        }
    }
stopwatch.Stop();
myInt++;
display();
}

都用这个:

private void display()
{   
    myListView.Items.Clear();
    myListView.Items.Add(new ListViewItem(new[] { myInt }));
}

(1) 和 (2) 将数字增加 5,但显示根本没有更新.它显示显示何时被其他功能更新.

(1) and (2) increment the number by 5 but the display is not updated at all. it shows when the display is updated by some other function.

(3) 和 (4) 将数字增加 5,但显示仅在大约 1500 毫秒后更新,显示跳过单个步骤并仅显示最终结果(例如 15).

(3) and (4) increment the number by 5, but the display is only updated after about 1500ms, the display skipping the single steps and displaying just the final result (eg 15).

有什么建议可以使这项工作顺利进行吗?我可以以某种方式强制刷新 display() 函数吗?

any suggestions to make this work? can i force a refresh in the display() function somehow?

为什么 t.Wait();导致异常?(我在网上找到了任务代码)

why does t.Wait(); cause an exception? (i found the task code somewhere on the net)

(5)

private void team_comm_btn_all_Click(object sender, EventArgs e)
{
    for (int i = 0; i < 5; i++) 
    {
            await Run(i); //error 74 see below
    }
}

private async Task Run(int i)
{
    myInt++;
    display();
    await Task.Delay(300);
}

等待运行(i);给出以下内容:错误 74 'await' 运算符只能在异步方法中使用.考虑使用async"修饰符标记此方法并将其返回类型更改为Task".

await Run(i); gives the following: Error 74 The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'.

只是执行Run(i)"而不是给出await"丢失的警告……在这种情况下,它会立即编译并递增 5.

just doing "Run(i)" instead gives a warning that "await" is missing... in this case it compiles and increments by 5 without any delay.

(6)

private void team_comm_btn_all_Click(object sender, EventArgs e)
{
   for (int i = 0; i < 5; i++) 
   {
       var task = Task.Run(async () =>
        {
            await Run(i);
        });
   }
}

private async Task Run(int i)
{
    myInt++;
    display();
    await Task.Delay(300);
}

增加 5 但根本不更新显示.

increments by 5 but does not update display at all.

推荐答案

通常您会使用 System.Windows.Forms.Timer 来解决这个问题.但是 async/await 一旦你理解它(并仔细阅读编译器警告和错误消息)就会使这些事情变得微不足道.很快,(5) 是解决编译器错误的小修改的方法.
但让我们从头开始.假设您首先编写这样的普通同步版本(基本上是您的(3))

Normally you would use System.Windows.Forms.Timer for that. But async/await makes such things trivial as soon as you understand it (and read carefully the compiler warning and error messages). Shortly, (5) is the way to go with a small modification resolving the compiler error.
But let start from the beginning. Assuming you first write a normal synchronous version like this (basically your (3))

private void team_comm_btn_all_Click(object sender, EventArgs e)
{
    for (int i = 0; i < 5; i++) 
    {
        if (i != 0) System.Threading.Thread.Sleep(300);
        myInt++;
        display();
    }
}

只是为了查看 UI 没有更新.所以你决定把它变成异步的,这在 async/await 的帮助下很容易用 Task.Delay 替换 Thread.Sleep 像这样

just to see that the UI is not updating. So you decide to turn it into asynchronous, which with the help of async/await is simple replacing Thread.Sleep with Task.Delay like this

private void team_comm_btn_all_Click(object sender, EventArgs e)
{
    for (int i = 0; i < 5; i++) 
    {
        if (i != 0) await Task.Delay(300);
        myInt++;
        display();
    }
}

但现在编译失败,出现以下错误

But now it fails to compile with the following error

错误 74 'await' 运算符只能在异步方法中使用.考虑使用async"修饰符标记此方法并将其返回类型更改为Task".

Error 74 The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'.

信息很清楚.您必须async 关键字标记您的方法.将返回类型更改为 Task 的其他建议如何,通常您应该考虑它,但由于您在事件处理程序中,即无法更改签名的方法,您可以忽略它部分 - 这就是为什么允许 async void 的确切情况.

The message is clear enough. You must mark your method with the async keyword. What about the other recommendation of changing the return type to Task, normally you should take it into consideration, but since you are inside a event handler, i.e. a method which signature cannot be changed, you can ignore that part - that's the exact case why async void is allowed.

总而言之,您的最终代码将如下所示

To conclude, your final code will look like this

private async void team_comm_btn_all_Click(object sender, EventArgs e)
{
    for (int i = 0; i < 5; i++) 
    {
        if (i != 0) await Task.Delay(300);
        myInt++;
        display();
    }
}

这篇关于如何使表单延迟显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆