Ari*_*ian 1 c# multithreading task c#-4.0
我想在列表框中添加一些文本Task,我只需使用一个按钮并在点击事件中放置此代码:
TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew(() =>
{
for (int i = 0; i < 10; i++)
{
listBox1.Items.Add("Number cities in problem = " + i.ToString());
System.Threading.Thread.Sleep(1000);
}
}, CancellationToken.None, TaskCreationOptions.None, uiScheduler);
Run Code Online (Sandbox Code Playgroud)
但是直到for循环结束它才能工作并且UI被锁定.
问题出在哪儿 ?
谢谢 :)
小智 7
您可以在线程中完成所有工作,但是当您需要更新UI时,请使用调度程序:
Task.Factory.StartNew(() =>
{
for (int i = 0; i < 10; i++)
{
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
new Action(() => {listBox1.Items.Add("Number cities in problem = " + i.ToString()); }));
System.Threading.Thread.Sleep(1000);
}
});
Run Code Online (Sandbox Code Playgroud)
哪里有问题?
好吧,你明确地说你想在 UI 线程中执行任务......然后你在任务中休眠,所以它阻塞了 UI 线程。您如何期望进入 UI 线程,但不会Thread.Sleep 引起问题?
如果您可以使用 C# 5 和 async/await,那会让事情变得更容易:
private static async Task ShowCitiesAsync()
{
for (int i = 0; i < 10; i++)
{
listBox1.Items.Add("Number cities in problem = " + i);
await Task.Delay(1000);
}
}
Run Code Online (Sandbox Code Playgroud)
如果您不能使用 C# 5(如您的标签所建议),那么它会更加棘手。您可能最好使用Timer:
// Note: you probably want System.Windows.Forms.Timer, so that it
// will automatically fire on the UI thread.
Timer timer = new Timer { Interval = 1000; }
int i = 0;
timer.Tick += delegate
{
listBox1.Items.Add("Number cities in problem = " + i);
i++;
if (i == 10)
{
timer.Stop();
timer.Dispose();
}
};
timer.Start();
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,它非常丑陋......并且它假设您不想在 UI 更新之间实际执行任何工作。
另一种选择是使用 ,在不同的线程上模拟长时间运行的任务(目前正在睡眠)BackgroundWorker,并使用ReportProgress返回 UI 线程来添加列表项。
| 归档时间: |
|
| 查看次数: |
10419 次 |
| 最近记录: |