私は、配列の大きさに等しい、配列内の整数のすべての可能な乗算を出力したアプリケーションexprementingています:大きな数のためにチェックされる必要がある場合はLINQクエリ自体は非常に時間がかかり、特別ですバックグラウンドワーカーによるLINQクエリの進行状況を報告します。
private void bgw_DoWork(object sender, DoWorkEventArgs e)
{
int progress = 0;
int toCheck = int.Parse(textBox2.Text); //Number to check for
int[] array = new int[toCheck];
//Fill the array
for (int i = 0; i < toCheck; i++)
{
array[i] = i;
bgw.ReportProgress(progress);
progress += 1;
}
var result =
from i1 in array
from i2 in array
where i1 * i2 == toCheck
let square = i1 * i2
select new { i1, i2, square }; //how to report progress here?
foreach (var res in result)
{
textBox1.Text += res.i1 + " * " + res.i2 + " = " + res.square + Environment.NewLine;
bgw.ReportProgress(progress);
progress += 1;
}
}
を。 linqクエリの進捗状況を報告する方法はありますか?または私はlinqを残して、この古い学校のモードを行う必要がありますか?
更新 これは私のコード全体です。進歩裁判は、半分になった後では満たされない。最初の半分は、配列が作成されているとき、2番目の部分は、コードがlinqクエリを実行しようとしたときです(これが、linqクエリでレポートを実行する必要がある理由です)!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
namespace BGWorkerTest
{
public partial class Form1 : Form
{
private PerformanceCounter cpuCounter;
private PerformanceCounter ramCounter;
string[] diagnosticInfo = new string[2] { string.Empty, string.Empty };
int toCheck = 0;
StringBuilder sb;
public Form1()
{
InitializeComponent();
//Diagnostics
cpuCounter = new PerformanceCounter();
cpuCounter.CategoryName = "Processor";
cpuCounter.CounterName = "% Processor Time";
cpuCounter.InstanceName = "_Total";
ramCounter = new PerformanceCounter("Memory", "Available KBytes");
}
private string[] GetDiagnostics()
{
diagnosticInfo[0] = string.Format("{0:0.##}", cpuCounter.NextValue()) + "%";
diagnosticInfo[1] = ramCounter.NextValue() + "MB";
return diagnosticInfo;
}
private void timerStStr_Tick(object sender, EventArgs e)
{
string[] temp = new string[2] { "", ""};
temp = GetDiagnostics();
ststrLabelCpu.Text = temp[0];
ststrLabelMem.Text = temp[1];
}
private void button1_Click(object sender, EventArgs e)
{
ststrProgBar.Minimum = 0;
ststrProgBar.Maximum = 0;
toCheck = int.Parse(textBox2.Text);
ststrProgBar.Minimum = 0;
ststrProgBar.Maximum = toCheck * 2;
ststrProgBar.Step = 1;
//Starts the backgroundworker process asynchronously
bgw.RunWorkerAsync();
}
private void bgw_DoWork(object sender, DoWorkEventArgs e)
{
int progress = 0;
int[] array = new int[toCheck + 1];
for (int i = 0; i < toCheck + 1; i++)
{
array[i] = i;
bgw.ReportProgress(progress);
progress += 1;
}
var result =
from i1 in array
from i2 in array
where i1 * i2 == toCheck
let square = i1 * i2
select new { i1, i2, square };
sb = new StringBuilder();
foreach (var res in result)
{
sb.AppendLine(res.i1 + " * " + res.i2 + " = " + res.square);
bgw.ReportProgress(progress);
progress += 1;
Application.DoEvents();
}
}
private void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
ststrProgBar.PerformStep();
}
private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
MessageBox.Show("Operation Cancelled");
}
else
{
MessageBox.Show("Operation Completed");
textBox1.Text = sb.ToString();
}
}
}
}
あなたは一致が見つかるたびに進行状況を報告しています。不一致が見つかるたびに進捗状況を報告しますか? – Rawling
私が書き込んだlinqのクエリで一致の発見を報告したところ、私は理解していませんか? forループの 'ReportProgress()'は、配列が作成されているということにすぎません。なぜなら、より大きなintが配列がいっぱいになるのにかなり時間がかかるからです。また、テキストボックスは、行が追加されるたびにレポートされます。私は実際のlinqクエリの内部に報告がありません。 –
Linqは遅延です。すべての一致を見つけてforeachループに渡すのではなく、それぞれが見つかると直ちに値をforeachループに渡します。したがって、foreachループ内のReportProgressは、一致が見つかるたびにレポートする必要があります。それが起こっていない場合(例:あなたは大規模な待って、多くの迅速なレポートに続いて - 私はなぜわからない。 – Rawling