编辑:Application.DoEvents();这样做了。在这里找到:Force GUI update from UI Thread
c#,winforms。我希望以1为步长增加一个数字,并在列表视图中显示这些增量,以便用户看到数字向上计数(例如从10到15)。
我有另一个按钮,单击时增加1,并使用相同的显示()。它工作正常,并按预期更新显示。
我尝试了这些代码(缩短以节省空间):
(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,但显示不会更新。它显示何时通过其他功能更新显示。
(3)和(4)将数字增加5,但显示仅在约1500ms后更新,显示屏跳过单步并显示最终结果(例如15)。
任何使这项工作的建议?我可以以某种方式强制刷新display()函数吗?
为什么t.Wait();引起异常? (我在网上的某个地方找到了任务代码)
编辑:
(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);
}
await Run(i);给出以下内容: 错误74'await'运算符只能在异步方法中使用。考虑使用'async'修饰符标记此方法并将其返回类型更改为'Task'。
只是做“Run(i)”而是发出警告“等待”丢失......在这种情况下,它会毫不拖延地编译并递增5。
(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但根本不更新显示。
答案 0 :(得分:0)
通常你会使用System.Windows.Forms.Timer
。但async/await
只要你理解它就会使这些事情变得微不足道(并仔细阅读编译器警告和错误信息)。不久,(5)是解决编译器错误的小修改的方法
但是从一开始就开始吧。假设您首先编写这样的正常同步版本(基本上是您的(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
的帮助下,将Thread.Sleep
替换为Task.Delay
就像这样简单
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();
}
}
但现在无法使用以下错误进行编译
错误74'await'运算符只能在异步方法中使用。考虑使用'async'修饰符标记此方法并将其返回类型更改为'Task'。
信息很清楚。您必须使用async
关键字标记您的方法。将返回类型更改为Task
的其他建议怎么样呢,通常你应该考虑它,但由于你在事件处理程序内部,即一个无法更改签名的方法,你可以忽略那部分 - 那是允许async void
的确切情况。
总而言之,您的最终代码将如下所示
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();
}
}