Использование анонимных делегатов с.NET ThreadPool. QueueUserWorkItem

Вы должны добавить свой динамический элемент управления в коллекцию элементов управления

int controlCounts = 0;

private void addControls_Click(object sender, EventArgs e)
{

    controlCounts++;

    TextBox txt_QTY = new TextBox();
    txt_QTY.Location = new Point(100 * controlCounts, 100);
    txt_QTY.Name = "txt_QTY" + controlCounts;
    Controls.Add(txt_QTY);
    txt_QTY.TextChanged += txt_QTY_TextChanged;

    TextBox txt_Price = new TextBox();
    txt_Price.Location = new Point(100 * controlCounts, 200);
    txt_Price.Name = "txt_Price" + controlCounts;
    Controls.Add(txt_Price);
    txt_Price.TextChanged += txt_Price_TextChanged;

    TextBox txt_Total = new TextBox();
    txt_Total.Location = new Point(100 * controlCounts, 300);
    txt_Total.Name = "txt_Total" + controlCounts;
    Controls.Add(txt_Total);
}

private void txt_QTY_TextChanged(object sender, EventArgs e)
{
    TextBox txt_QTY = (TextBox)sender;
    string index = txt_QTY.Name.Substring("txt_QTY".Length);
    updateTotal(index);
}

private void txt_Price_TextChanged(object sender, EventArgs e)
{
    TextBox txt_Price = (TextBox)sender;
    string index = txt_Price.Name.Substring("txt_Price".Length);
    updateTotal(index);
}

private void updateTotal(string index)
{
    TextBox txt_QTY = (TextBox)Controls["txt_QTY" + index];
    TextBox txt_Price = (TextBox)Controls["txt_Price" + index];
    TextBox txt_Total = (TextBox)Controls["txt_Total" + index];

    if ((txt_QTY.Text != "") && (txt_Price.Text != ""))
    {
        txt_Total.Text = (Convert.ToInt32(txt_QTY.Text) * Convert.ToInt32(txt_Price.Text)).ToString();
    }

}
.
6
задан Alessandro Muzzi 28 May 2018 в 09:15
поделиться

3 ответа

Это корректно, и описывает, как C# получает внешние переменные в закрытиях. Это не непосредственно проблема о параллелизме, а скорее об анонимных методах и лямбда-выражениях.

Этот вопрос обсуждает эту функцию языка и ее последствия подробно.

7
ответ дан 10 December 2019 в 02:54
поделиться

Ниже детализация ссылки, почему это происходит. Это записано для VB, но C# имеет ту же семантику.

http://blogs.msdn.com/jaredpar/archive/2007/07/26/closures-in-vb-part-5-looping.aspx

1
ответ дан 10 December 2019 в 02:54
поделиться

Это - обычное явление при использовании закрытий и особенно очевидно при построении запросов LINQ. Закрытие ссылается на переменную, не ее содержание, поэтому, чтобы заставить Ваш пример работать, можно просто указать переменную в цикле, который принимает значение t и затем ссылки это в закрытии. Это гарантирует, что каждая версия Вашего анонимного делегата ссылается на различную переменную.

1
ответ дан 10 December 2019 в 02:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: