gpt4 book ai didi

c# - 在 Parallel.ForEach 中监控进度

转载 作者:太空狗 更新时间:2023-10-30 01:10:05 26 4
gpt4 key购买 nike

尝试监视 Parallel.ForEach 循环的进度 我已经尝试了 this question 中提出的建议但不幸的是,我仍然无法完成我想要的。

基本上,我在尝试建议的实现(使用计时器)时遇到的第一个问题是 Parallel.ForEach 方法是一个阻塞调用,因此没有发生计时器滴答回调。

所以我尝试将 Parallel.ForEach 循环放在后台工作线程中。这确实允许发生计时器滴答事件,但在 ForEach 操作完成之前,我的计数器值永远不会更新。

这是代码的基本思想(与后台 worker )。

private StockList _StockListToProcess = null;

private static Int64 ItemsProcessed = 0;

private System.Windows.Threading.DispatcherTimer _timer = null;

private System.ComponentModel.BackgroundWorker _backWorker = null;

progressBar1.Minimum = 1;
progressBar1.Maximum = this._StockListToProcess.Count;

MainWindow.ItemsProcessed = 0;

this._timer = new System.Windows.Threading.DispatcherTimer();
this._timer.Interval = TimeSpan.FromMilliseconds(100);
this._timer.Tick += timer_Tick;
this._timer.Start();

this._backWorker = new System.ComponentModel.BackgroundWorker();

this._backWorker.DoWork += delegate(object o, System.ComponentModel.DoWorkEventArgs args)
{
Parallel.ForEach(this._StockListToProcess, new ParallelOptions() { MaxDegreeOfParallelism = 5 },
(Stock stock) =>
{
MyWebServiceClient serviceClient = new MyWebServiceClient ();
MyWebServiceClient.ResponseEnum result = (MyWebServiceClient .ResponseEnum)serviceClient.SetProductPricing(token.LoginName, token.LoginPassword, token.SiteID.ToString(), stock.ProductCode, stock.ProductPrice);
System.Threading.Interlocked.Increment(ref MainWindow.ItemsProcessed);
});

this._timer.Stop();
};

private void timer_Tick(object sender, EventArgs e)
{
progressBar1.Value = MainWindow.ItemsProcessed;
}

我错过了什么?

最佳答案

我要试探性地说,定时器和后台工作人员的嵌套会让您感到悲伤。

如果可能,我建议您避免使用 Reactive Extensions for .NET (Rx) .

如果你这样做的话,你的代码会是这样的:

progressBar1.Minimum = 1;
progressBar1.Maximum = this._StockListToProcess.Count;

var itemsProcessed = 0;
var updater = new Subject<Unit>(Scheduler.Dispatcher);
updater.Subscribe(u =>
{
itemsProcessed += 1; //Rx serializes "OnNext" calls so this is safe.
progressBar1.Value = itemsProcessed;
});

Parallel.ForEach(this._StockListToProcess, new ParallelOptions() { MaxDegreeOfParallelism = 5 },
(Stock stock) =>
{
MyWebServiceClient serviceClient = new MyWebServiceClient ();
MyWebServiceClient.ResponseEnum result = (MyWebServiceClient .ResponseEnum)serviceClient.SetProductPricing(token.LoginName, token.LoginPassword, token.SiteID.ToString(), stock.ProductCode, stock.ProductPrice);
updater.OnNext(new Unit());
});

updater.OnCompleted();

我使用一段虚拟代码进行了测试,结果运行良好,因此,如果您足够勇敢,应该能够毫不费力地运行它。 :-)

关于c# - 在 Parallel.ForEach 中监控进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5415398/

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