.net 4.5和任务.要使用的



我一直在.net 4.5中引入的异步/等待语法上阅读并得到它。

我找到了一个简单的示例。我尝试了其中一个样品(填充空白)

form1上带1个按钮的代码:

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线程被阻止,或者我相信它被阻止了,因为代码运行时无法移动窗口。如果我评论任务。

所以我在这里误解了一些东西吗?我知道使用doevents等是不好的练习,但是我有一些遗产代码,我对此负责,我的目标是用产量代替它,因为它是最好的选择。但是首先,我需要使用异步/等待。

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
}

最新更新