4

Task 関数をいじっていて、Task を for ループで実行し、パラメータを関数 (i) に渡すという非常に奇妙な問題が見つかりました (i) ループ カウントは 100 です。予想どおり、出力は次のようになります。
1
2
3
4
5
しかし、この関数から得られる出力は
100
100
100
です。これは、新しいパラメーターに変更されないことを意味します。詳細については、プロジェクト全体をアップロードしました。

私が作ったサンプルプログラムをダウンロード!

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        CheckForIllegalCrossThreadCalls = false;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Task.Factory.StartNew(() => button_tast());
    }
    void button_tast()
    {
        Task[] tk =new Task[100];
        for (int i = 0; i < 100; i++)
        {
            tk[i] = Task.Factory.StartNew(() => taskThread(i));
        }
        Task.WaitAll(tk);
    }
void taskThread(int i){
    listBox1.Items.Add(i);
}
}
}
4

2 に答える 2

8

これは、ループ変数を閉じているためです。ループを次のように書き換えることができます

for (int i = 0; i < 100; i++)
{
    int taskNumber = i
    tk[i] = Task.Factory.StartNew(() => taskThread(taskNumber));
}

そしてあなたは元気になるでしょう

于 2013-05-20T14:37:49.240 に答える
0

問題は、タスクの観点から、変数iがグローバルであり、非スレッドセーフな方法で変更できることです。これは簡単に修正できますが....

        for (int i = 0; i < 100; i++)
        {
            int localCopy = i;
            tk[i] = Task.Factory.StartNew(() => taskThread(localCopy));
        }
于 2013-05-20T14:39:24.563 に答える