Reputation: 727
I am having a problem for a while
this line:
txtPastes.Text = (string)e.UserState;
throws a cross thread exception and I didn't find any solution
txtPastes
- textbox
GuiUpdate
- BackgroundWorker
lstAllPastes
- list of string
private void GuiUpdate_DoWork(object sender, DoWorkEventArgs e)
{
while (true)
{
while (lstAllPastes.Count == 0) ;
for (int i = 0; i < lstAllPastes[0].Length; i++)
{
GuiUpdate.ReportProgress(0, lstAllPastes[0].Substring(0, i));
Thread.Sleep(1);
}
lstAllPastes.RemoveAt(0);
}
}
private void GuiUpdate_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
txtPastes.Text = (string)e.UserState;
}
private void GuiUpdate_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
Upvotes: 0
Views: 5959
Reputation: 54877
You cannot update a UI control from any thread other than the UI thread. Typically, the BackgroundWorker
would take care of raising its ProgressChanged
and RunWorkerCompleted
events correctly on the UI thread. Since that doesn’t appear to be the case here, you could marshal your UI-updating logic to the UI thread yourself by using the Invoke
method:
txtPastes.Invoke(new Action(() =>
{
// This code is executed on the UI thread.
txtPastes.Text = (string)e.UserState;
}));
If you’re on WPF, you would need to call Invoke
on the control’s dispatcher:
txtPastes.Dispatcher.Invoke(new Action(() =>
{
txtPastes.Text = (string)e.UserState;
}));
Update: As Thomas Levesque and Hans Passant have mentioned, you should investigate the reason why your ProgressChanged
event is not being raised on the UI thread. My suspicion is that you’re starting the BackgroundWorker
too early in the application initialization lifecycle, which could lead to race conditions and possibly a NullReferenceException
if the first ProgressChanged
event is raised before your txtPastes
textbox has been initialized.
Upvotes: 5
Reputation: 941337
Well, this is supposed to work of course. The cause of this exception is not visible in your snippet. What matters is exactly where and when the BackgroundWorker is started. Its RunWorkerAsync() method uses the SynchronizationContext.Current property to figure out what thread needs to execute the ProgressChanged event handler.
This can go wrong when:
Upvotes: 2
Reputation: 292405
Make sure you start the BackgroundWorker
from the UI thread; if you do that, the ProgressChanged
event will be raised on that thread, and the exception won't happen.
Upvotes: 1