gpt4 book ai didi

delay - .Net 4.5 和 Task.Yield vs Task.Delay 作为 DoEvents 的替代品?使用哪个?

转载 作者:行者123 更新时间:2023-12-04 11:09:09 29 4
gpt4 key购买 nike

我一直在阅读 .Net 4.5 中引入的 async/await 语法并对其有所了解。

我找到了简单的示例,其中 Task.Yield 是要走的路,而不是 Application.DoEvents。我尝试了其中一个样本(填空)

带有 1 个按钮的 Form1 上的代码:

public async void button1_Click(object sender, EventArgs e) {
var list = new List<int>();
for (int i = 0; i < 10000; i++) {
list.Add(i);
}
for (int i = 0; i < list.Count; i++) {
Process(list[i]);
await Task.Yield();
//await Task.Delay(1);
}
}

public static void Process(int i) {
Debug.WriteLine(i);
}

但是,运行这段代码时,UI 线程被阻塞了,或者我认为它被阻塞了,因为我无法在代码运行时移动窗口。如果我注释掉 Task.Yield() 并改为使用 Task.Delay(1) 行,则 GUI 是响应式的。

所以我是不是误解了什么?我知道使用 DoEvents 之类的是不好的做法,但我有一些我负责的遗留代码使用它,我的目标是用 Yield 替换它,因为它是最好的选择。但首先我需要熟悉 async/await。

最佳答案

async不会神奇地使您的代码变得更好。 Yield不是 DoEvents 的直接替代品(这是邪恶的)。更改代码的对齐方式需要一些工作。

只要您不需要 UI 上下文,就可以将您的工作推到线程池中:

public async void button1_Click(object sender, EventArgs e) {
await Task.Run(() => {
var list = new List<int>();
for (int i = 0; i < 10000; i++) {
list.Add(i);
}
for (int i = 0; i < list.Count; i++) {
Process(list[i]);
}
});
}

或者,您可以考虑使用 IProgress<T> 分解特定于 UI 的部分或使用 Task.Run对于非 UI 工作:

public async void button1_Click(object sender, EventArgs e) {
var list = new List<int>();
await Task.Run(() => {
for (int i = 0; i < 10000; i++) {
list.Add(i);
}
});

for (int i = 0; i < list.Count; i++) {
await ProcessAsync(list[i]);
}
}

public static async Task ProcessAsync(int i) {
await Task.Run(() => { ... }); // background
myUi.Text = i.ToString() + " working"; // ui
await Task.Run(() => { ... }); // more background
myUi.Text = i.ToString() + " complete"; // ui
}

关于delay - .Net 4.5 和 Task.Yield vs Task.Delay 作为 DoEvents 的替代品?使用哪个?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13123957/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com