Problem med C#.NET Background Worker
Hej
Jobbar lite med ett Word Add-in som ska förenkla utskrifter samt ha fackhantering.
Det jag vill göra är en sökning på skrivaren och lista alla tillgängliga fack skrivardrivrutiner erbjuder, denna process kan ta en liten tid därför hade jag tänkt att låta den gå i en backgroundworker för att inte få GUI att totallåsa sig.
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
int rawKind;
PrintDocument p = new PrintDocument();
p.PrinterSettings.PrinterName = e.Argument.ToString();
List<string> items = new List<string>();
for (int j = 0; j < p.PrinterSettings.PaperSources.Count; j++)
{
rawKind = Convert.ToInt32(p.PrinterSettings.PaperSources[j].GetType().GetField("kind",
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.NonPublic).GetValue(p.PrinterSettings.PaperSources[j]));
items.Add(p.PrinterSettings.PaperSources[j].SourceName.Trim());
backgroundWorker1.ReportProgress(Convert.ToInt32(j * 100 / p.PrinterSettings.PaperSources.Count));
if (backgroundWorker1.CancellationPending)
{
e.Cancel = true;
break;
}
}
e.Result = items;
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//Här får jag felet!
toolStripProgressBar1.Value = e.ProgressPercentage;
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
MessageBox.Show("Sökningen avbruten");
}
else
{
MessageBox.Show("Sökningen klar");
}
}
private void searchTrayBtn_Click(object sender, EventArgs e)
{
if (!backgroundWorker1.IsBusy)
{
backgroundWorker1.RunWorkerAsync(printerListBox.SelectedItem.ToString());
searchTrayBtn.Text = "Avbryt";
}
else
{
backgroundWorker1.CancelAsync();
}
}
När koden anropar backgroundWorker1_ProgressChanged och ändrar värdet på toolStripProgressBar1 så hänger det sig och så får jag felmeddelandet
System.InvalidOperationException was unhandled
Message=Åtgärden mellan trådar är inte giltig: Kontrollen hämtade från en annan tråd än den tråd som den skapades på.
Source=System.Windows.Forms
StackTrace:
vid System.Windows.Forms.Control.get_Handle()
vid System.Windows.Forms.Control.SendMessage(Int32 msg, Int32 wparam, Int32 lparam)
vid System.Windows.Forms.ProgressBar.UpdatePos()
vid System.Windows.Forms.ProgressBar.set_Value(Int32 value)
vid System.Windows.Forms.ToolStripProgressBar.set_Value(Int32 value)
vid Byråstöd.PrintSettingsForm.backgroundWorker1_ProgressChanged(Object sender, ProgressChangedEventArgs e) i C:\Users\andreas\Documents\Visual Studio 2010\Projects\Byråstöd\Byråstöd\PrintSettingsForm.cs:rad 84
vid System.ComponentModel.BackgroundWorker.OnProgressChanged(ProgressChangedEventArgs e)
vid System.ComponentModel.BackgroundWorker.ProgressReporter(Object arg)
vid System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
vid System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
vid System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
vid System.Threading.ThreadPoolWorkQueue.Dispatch()
vid System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
InnerException:
Det fungerar hur fint som helst om jag skippar progressbaren och andra UI grejjer. Men grejjen med backgroundsworkers är ju att man ska kunna köra en tråd i bakgrunden och ändå kunna påverka UI detaljer via events.