监控 Parallel.ForEach 的进度

发布于 2024-10-26 12:29:24 字数 1855 浏览 1 评论 0原文

尝试监视 Parallel.ForEach 循环的进度我已经尝试了 这个问题中提出的建议 但不幸的是我仍然无法实现我想要的。

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

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

这是代码的基本思想(与后台工作者)。

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

我错过了什么?

Attempting to monitor progress of a Parallel.ForEach loop I have tried the suggestion put forward in this question but unfortunately I have still been unable to accomplish what I wanted.

Basically the first problem I ran into when I attempted the implementation suggested (using a timer) was that the Parallel.ForEach method is a blocking call and hence the timer-tick callback was not occurring.

So I tried putting the Parallel.ForEach loop inside of a background worker thread. Which did infact allow for the timer-tick event to occur but my counter value is never updated until the ForEach operation is complete.

Here is the basic idea of the code (with the backgroundworker).

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

What am I missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

鸠书 2024-11-02 12:29:24

我要尝试说定时器和后台工作者的嵌套正在给你带来悲伤。

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

如果您这样做,您的代码将如下所示:

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

我使用一段虚拟代码进行了测试,它工作得很好,因此,如果您足够勇敢,您应该能够毫无困难地运行它。 :-)

I'm going to take a stab at saying the nesting of timers and background workers is causing you grief.

If possible, I suggest you avoid then in favour of using the Reactive Extensions for .NET (Rx).

This is what your code would look like if you did:

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

I did a test using a dummy bit of code and it worked fine so, if you are brave enough, you should be able to get this running without to much difficulty. :-)

柠檬色的秋千 2024-11-02 12:29:24

尽管我确实很欣赏 Enigmativity 发布的解决方案,但经过一番搜索后,我发现了我认为解决此问题的正确实现。一种不需要任何其他框架来实现的框架。

有关完整概述 请参阅这篇文章。

Although I do appreciate the solution posted by Enigmativity after some searching I have found what I consider the correct implementation for solving this problem. One that does not require any other frameworks to implement.

For a full overview please see this article.

风流物 2024-11-02 12:29:24

如果您在主线程中使用普通计时器并通过 ConcurrentDictionary 传递信息会怎样?

What if you use a normal timer in your main thread and pass information via a ConcurrentDictionary?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文