A už výše Vám pan Linhart řekl, že nelze z vedlejšího vlákna (ve vašem případě metoda nacti()) přistupovat k ovládacím prvkům hlavního vlákna. Použijte BackgroundWorker. BackgroundWorker má události: DoWork - Zde si vykonáte načítání ProgressChanged - Zde si budete upravovat UI RunworkerCompleted - Zde si vrátíte data pro grid. Ale pokud jsem správně pochopil, že chcete aby při načítání se zároveň aktualizoval progressbar i datagrid, tak jsem zkusil aktualizovat v progresschanged, přes parametr UserState a také to funguje. Jen je potřeba ověřovat dostupnost Ui prvků (při běžícím vlákně a ukončení aplikace). Je to v C# ale s tím si poradíte.
//Instance backgroundworkeru
private readonly BackgroundWorker _bw;
public Form1()
{
InitializeComponent();
//inicializace backgrounworker
_bw = new BackgroundWorker { WorkerReportsProgress = true };
//události - do work je událost v jiném vlákně
_bw.DoWork += Bw_DoWork;
//progress changed událost mění hodnoty v hlavním vlákně
_bw.ProgressChanged += BwProgressChanged;
}
//Pokud budete potřebovat do této metody dostat nějaká jiná data,
//tak jako parametr v RunWorkerAsync, já tam mám pouze seznam souborů
void Bw_DoWork(object sender, DoWorkEventArgs e)
{
var worker = sender as BackgroundWorker;
var soubory = e.Argument as List<string>;
if (soubory == null || worker == null) return;
for (var i = 0; i < soubory.Count; i++)
{
var fi = new System.IO.FileInfo(soubory[i]);
//výstup pro datagrid předávám jako pole objektů
var result = new object[]
{
i+1,
"Nějaký text",
DateTime.Parse("12.3.2014"),
fi.FullName,
GetSha(fi.FullName),
DateTime.Now
};
worker.ReportProgress(i, result);
}
}
//Dlouho trvající operace
private string GetSha(string fileName)
{
var result = fileName.GetHashCode();
System.Threading.Thread.Sleep(200);
return result.ToString(CultureInfo.InvariantCulture);
}
//aktualizace ui a načítání do datagridu
private void BwProgressChanged(object sender, ProgressChangedEventArgs e)
{
//ukončení vlákna, při ukončení aplikace
if (progressBar1 == null || dataGridView1 == null)
{
_bw.CancelAsync();
return;
}
progressBar1.Value = e.ProgressPercentage;
dataGridView1.Rows.Add((object[])e.UserState);
}
//start úlohy
private void button1_Click(object sender, EventArgs e)
{
if (_bw.IsBusy) return;
var soubory = System.IO.Directory.GetFiles("C:\\Windows").ToList();
progressBar1.Maximum = soubory.Count - 1;
_bw.RunWorkerAsync(soubory);
}
Jo a v datagridu musíte mít správný počet sloupců, jinak to spadne, ale na to by jste přišel.
|