2

関数が別のスレッドで正しく実行されるように、関数にスレッド パラメーターを指定する必要がある C# プログラムを作成しています。具体的には、パラメーターの 1 つは、アクセスするファイルの文字列名です。問題は、ファイルの名前をリストに保存していて、リストから値にアクセスしていることです。ただし、これを行うと、1 つまたは 2 つのスレッドが作成された後で、インデックスが範囲外というエラーが発生します。これは文字列のリストだと思いますが、インデックスが範囲外ではないことはわかっています。

パラメータを渡す方法が間違っているのか、それとも他に何が間違っているのかわかりません。

これは私の C# コードのサンプルです (呼び出された関数のコードを除く):

for (int i = 0; i < 5; i++)
            {
                surfaceGraphDataNames.Add(String.Format(surfacePlotDataLocation+"ThreadData{0}.txt", i));
                try
                {
                    generateInputFile(masterDataLocation);
                }
                catch
                {
                    MessageBox.Show("Not enough data remaining to create an input file");
                    masterDataLocation = masterDataSet.Count - ((graphData.NumRootsUsed + 1) * (graphData.Polynomial + 1) - 1);
                    this.dataSetLabel.Text = String.Format("Current Data Set: {0}", masterDataLocation + 1);
                    return;
                }
                try
                {
                    //creates the data in a specific text file I hope
                    createSurfaceGraph(surfaceGraphDataNames[i]);
                    //start threads 
                    threadsRunning.Add(new Thread(() => runGnuplotClicks(surfaceGraphDataNames[i], masterDataLocation)));
                    threadsRunning[i].Start();
                }
                catch
                {
                    this.graphPictureBox1.Image = null;//makes image go away if data fails
                    MessageBox.Show("Gridgen failed to generate good data");
                }
                masterDataLocation++;
            }
4

3 に答える 3

0

最も明らかな問題は、ループ変数を閉じていることです。ラムダ式を構築する場合、変数参照は変数自体に対するものであり、そのではありません。あなたの例から取られた次のコードを考えてみましょう。

for (int i = 0; i < 5; i++)
{
  // Code omitted for brevity.

  new Thread(() => runGnuplotClicks(surfaceGraphDataNames[i], masterDataLocation))

  // Code omitted for brevity.
}

これが実際に行っているのは、変数のキャプチャですi。しかし、スレッドが実行を開始するiまでに、 の値が現在 5 になっているポイントまで数回インクリメントされている可能性がありIndexOutOfRangeExceptionますsurfaceGraphDataNames。あなたのスレッドが、iあなたが思っていた の値を使用していないという事実を気にしないでください。

これを修正するには、特別なキャプチャ変数を作成する必要があります。

for (int i = 0; i < 5; i++)
{
  // Code omitted for brevity.

  int capture = i;
  new Thread(() => runGnuplotClicks(surfaceGraphDataNames[capture], masterDataLocation))

  // Code omitted for brevity.
}
于 2013-09-03T14:22:49.300 に答える
0

私はこのような問題を抱えていたので、スレッドを使用しています。インデックスが範囲外ではないことは確かであり、ブレークポイントで停止して続行した場合、この状況は発生しませんでした。スレッドの代わりにタスクを使用してみてください。できます

于 2013-09-03T03:25:48.350 に答える