我正在尝试迭代队列-从队列中获取1个条目,在后台任务中处理它,更新UI,然后获取下一个条目,依此类推。问题是第一个项目是在后台任务(线程)中处理的,而随后的项目是在UI线程中处理的-阻塞了UI。
有谁知道为什么会发生这种情况,以及如何解决这个问题?我的完整测试代码如下。注意:这段代码仅供我学习和将来参考-不是任何实际的应用程序。
public partial class MainWindow : Window
{
private Queue<int> testQueue = new Queue<int>();
private TaskScheduler uiScheduler;
public MainWindow()
{
InitializeComponent();
this.uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
this.testQueue = new Queue<int>();
this.testQueue.Enqueue(3);
this.testQueue.Enqueue(6);
this.testQueue.Enqueue(7);
this.testQueue.Enqueue(11);
this.testQueue.Enqueue(13);
}
// just a method that takes about 1 second to run on a modern pc
private double SumRootN(int root)
{
double result = 0;
for (int i = 1; i < 10000000; i++)
{
result += Math.Exp(Math.Log(i) / root);
}
return result;
}
private void testQueueButton_Click(object sender, RoutedEventArgs e)
{
this.processQueue();
}
private void processQueue()
{
if (this.testQueue.Count > 0)
{
int root = this.testQueue.Dequeue();
Task<double>.Factory.StartNew(() => SumRootN(root))
.ContinueWith(t =>
{
this.statusText.Text += String.Format("root {0} : {1}\n", root, t.Result);
this.processQueue();
}, uiScheduler);
}
else
{
this.statusText.Text += "Done\n";
}
}
}发布于 2012-06-25 06:37:09
谢谢你贴了一张复制品,让我可以调试。
Task.Factory.StartNew在调度程序(factoryScheduler ?? currentTaskScheduler ?? threadPoolScheduler)上运行您的任务。您进入了情况2:您的新任务从其父任务继承调度程序。
我注意到你奇怪地使用递归调用来模拟循环。如果你这样做,问题就会消失:
Task<double>.Factory.StartNew(() => SumRootN(root))
.ContinueWith(t =>
{
this.statusText.Text += String.Format("root {0} : {1}\n", root, t.Result);
}, uiScheduler).ContinueWith(t => { this.processQueue(); });发布于 2012-06-25 06:22:50
那是因为你使用的是TaskScheduler.FromCurrentSynchronizationContext() --你知道它是做什么的,对吧?(使其在调用的同一线程上运行,在本例中为UI)
编辑:用户回答了为什么会发生这种情况,但您也可以这样做(对于准并行处理):
int root = this.testQueue.Dequeue();
Task<double>.Factory.StartNew(() => SumRootN(root))
.ContinueWith(t =>
{
this.statusText.Text += String.Format("root {0} : {1}\n", root, t.Result);
}, uiScheduler);
this.processQueue();https://stackoverflow.com/questions/11181640
复制相似问题