gpt4 book ai didi

c# - 递归任务队列

转载 作者:行者123 更新时间:2023-11-30 15:38:39 25 4
gpt4 key购买 nike

我正在尝试遍历队列 - 从队列中取出 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";
}
}
}

最佳答案

感谢您发布允许我进行调试的重现。

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(); });

关于c# - 递归任务队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11181640/

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