У меня есть проект, закодированный в .NET Winforms.
Мне нужно реализовать операцию интеллектуального анализа данных, распечатать текст в TextBox и обновить прогресс.
Я пытался использовать BackgroundWorker, но он выдает InvalidOperationException ( Операция с несколькими потоками недопустима: доступ к элементу управления xxxxx осуществляется из потока, отличного от потока, который был создан в )
Чтобы сузить потенциальные причины проблемы, я начал новый проект, включающий следующее:
Кнопка - чтобы запустить BackgroundWorker
Метка - для печати текста.
И ПрогрессБар.
Однако результат тот же. Я искал на SOF, и мне сказали использовать делегата, но я не знаком с ним.
Это пример кода, который выдает ошибку:
using System;
using System.Collections.Generic;
using System.ComponentModel;
namespace TestProject
{
public partial class Form1 : Form
{
private readonly BackgroundWorker _bw = new BackgroundWorker();
public Form1()
{
InitializeComponent();
_bw.DoWork += RosterWork;
_bw.ProgressChanged += BwProgressChanged;
_bw.RunWorkerCompleted += BwRunWorkerCompleted;
_bw.WorkerReportsProgress = true;
_bw.WorkerSupportsCancellation = false;
}
private void RosterWork(object sender, DoWorkEventArgs doWorkEventArgs)
{
for (int i = 0; i < 1000; i++)
{
label1.Text = i.ToString();
_bw.ReportProgress(Convert.ToInt32((i * (100 / 1000))));
}
}
private void BwProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
private void btnStart_Click(object sender, EventArgs e)
{
progressBar1.Show();
_bw.RunWorkerAsync();
}
private void BwRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
progressBar1.Hide();
}
}
}
Обновление:
Я следую ответу Джона Скита, он действительно работает над моим тестовым проектом, но вернемся к моему реальному проекту,
Макет моей формы:
Форма -
TabControl
- Tab1
-Tab1Panel
-TextBox1
Когда достигните этой линии:
TextBox txtbox1 = new TextBox();
Tab1Panel.Controls.Add(txtbox1);
Ошибка по-прежнему возникает при программном добавлении текстового поля в панель управления.
Наконец, я заменяю на это:
if (Tab1Panel.InvokeRequired)
Tab1Panel.Invoke((MethodInvoker)delegate { Tab1Panel.Controls.Add(txtbox1); });
else
Tab1Panel.Controls.Add(txtbox1);
Все работает. Как определить, является ли элемент управления InvokeRequired, указан ли этот элемент управления?