У меня есть этот фрагмент кода:
private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
remplirDataGrid();
}
private void frmChercherActesLoad(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void remplirDataGrid()
{
dataGridView1.DataSource = ActeServices.getAllActes(0, 40);
dataGridView1.Columns[0].Visible = false;
dataGridView1.Columns[1].HeaderText = "Code acte";
dataGridView1.Columns[2].HeaderText = "Désignation";
dataGridView1.Columns[3].HeaderText = "Pris en charge";
dataGridView1.Columns[4].HeaderText = "Id article";
dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
}
И вот метод getAllActe
:
public static IEnumerable<Acte> getAllActes(int skipCount, int takeCount)
{
var myTableAdapter = new SmartDocDALServices.SmartDocDataSetTableAdapters.actesTableAdapter();
myTableAdapter.Fill(myDataSet.actes);
var myResult = from q in myDataSet.actes.AsEnumerable()
select new Acte
{
code = q.code,
designation = q.designation,
priseEnCharge = q.prise_en_charge,
idArticle = q.id_article,
};
if (skipCount != -1)
myResult.Skip(skipCount);
if (takeCount != -1)
myResult.Take(takeCount);
IEnumerable<Acte> myResultRet = myResult.ToList();
return myResultRet;
То, что мне нравится делать, должно заполнить мой datagridview
использование второстепенного рабочего, после того как я запускаю приложение, я получил эту ошибку:
Операция межпотока, не допустимая: Управление 'dataGridView1 было предметом доступа от потока кроме того, который это было создано.
Я пробую это
private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
IEnumerable<Acte> result = ActeServices.getAllActes(0, 40);
backgroundWorker1.ReportProgress(0, result);
}
void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
dataGridView1.DataSource = (IEnumerable<Acte>)e.UserState;
dataGridView1.Columns[0].Visible = false;
dataGridView1.Columns[1].HeaderText = "Code acte";
***
но ничто полученное вовремя?. Я хотел бы это обновление datagrid, когда BGW загружает данные foreash загрузка данных, это добавляет его к DGV
Вы не можете обновить пользовательский интерфейс из потока BackgroundWorker.
Вам нужно отправить событие в пользовательский интерфейс, а затем получить что-то вроде:
private void EventHandler(object sender, YourEventArgs e)
{
if (this.dataGridView1.InvokeRequired)
{
this.dataGridView1.Invoke((MethodInvoker)delegate { this.AddToGrid(e.YourData); });
}
else
{
this.AddToGrid(e.YourData);
}
}
Это потому, что данные графического интерфейса пользователя не могут быть изменены из других потоков, кроме потока графического интерфейса. Чтобы исправить это, вам нужно вызвать изменения в потоке графического интерфейса пользователя с помощью диспетчера.
DataGrid необходимо настроить заранее, поэтому все, что вы делаете в асинхронной операции, - это заполняете данные.
var data = ActeServices.getAllActes(0, 40);
Dispatcher.BeginInvoke( new Action( () => { dataGridView1.DataSource = data; }))
DataGridView не является потокобезопасным. Однако установка DataSource, если данные уже доступны, должна быть достаточно быстрой.
Я бы порекомендовал:
Используйте BackgroundWorker только для загрузки данных в другой поток.
Установите DataSource и другие модификации datagridview в событии RunWorkerCompleted (вы можете передать результат из метода DoWork в Событие завершено установкой
e.Result = ActeServices.getAllActes (0, 40);
Необязательно: установите для dataGridView1.AutoGenerateColumns значение false и вручную добавьте столбцы либо в конструкторе Windows Forms, либо в коде, чтобы избежать мерцания.
Класс BackgroundWorker был разработан для выполнения длительной операции в фоновом потоке. Поскольку вам разрешен доступ к компонентам пользовательского интерфейса только из потока, который их создал, вы можете использовать Событие RunWorkerCompleted класса BackgroundWorker для обновления пользовательского интерфейса после завершения работы обработчика DoWork. Кроме того, вы можете безопасно обновить пользовательский интерфейс выполнения, используя событие ProgressChanged класса BackgroundWorker.