Accessing UI Control from BackgroundWorker Thread
Here's a snippet which I find very handy:
public static void ThreadSafe(Action action)
{
Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Normal,
new MethodInvoker(action));
}
You can pass it any delegate of Action
type or simply a lambda like this:
ThreadSafe(() =>
{
[your code here]
});
or
ThreadSafe(listBoxServers.Items.Clear);
Background worker proper way to access UI
You can pass data into the worker via the argument of the RunWorkerAsync call and pass data out via DoWorkEventArgs.Result...
class AuthUserData
{
public string Name;
public string Password;
}
private void button1_Click(object sender, EventArgs e)
{
var authData = new AuthUserData() { Name = textBox1.Text, Password = textBox2.Text };
worker.RunWorkerAsync(authData);
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
// On the worker thread...cannot make UI calls from here.
var authData = (AuthUserData)e.Argument;
UserManagement um = new UserManagement(sm.GetServerConnectionString());
e.Result = um;
e.Cancel = um.AuthUser(textBox1.Text, textBox2.Password));
}
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Back on the UI thread....UI calls are cool again.
var result = (UserManagement)e.Result;
if (e.Cancelled)
{
// Do stuff if UserManagement.AuthUser succeeded.
}
else
{
// Do stuff if UserManagement.AuthUser failed.
}
}
How to directly access the UI thread from the BackgroundWorker thread in WPF?
Have you looked at using Dispatcher.Invoke?
Dispatcher.Invoke(new Action(() => { Button_Start.Content = i.ToString(); }));
Or use BeginInvoke if you want something to happen asynchronously.
Can I update UI from BackgroundWorker.RunWorkerCompleted
Your code doesn't have a UI thread. Since you don't have a UI thread, and didn't call RunWorkerAsync
from a UI thread (which is required for it to know what UI thread to marshall the event handlers to) it can't call any of the event handlers in a (non-existent) UI thread.
Create a UI application (a winforms or WPF application, for example), make sure to create and run the BGW from a UI thread, and then you'll see that you can manipulate the controls from the various events (other than DoWork
, obviously).
Access windows control from Backgroundworker DoWork
You can only access Windows Forms controls from the GUI thread. If you want to manipulate them from another thread, you will need to use the Control.Invoke method to pass in a delegate to execute on the GUI thread. In your situation, you should be able to do this:
private void bgwBackground_DoWork(object sender, DoWorkEventArgs e)
{
foreach (Control controlOut in LayoutPanel1.Controls)
{
this.Invoke(new MethodInvoker(delegate {
// Execute the following code on the GUI thread.
string myString = controlOut.Name;
}));
}
}
I like to define an extension method that allows me to use the cleaner lambda syntax:
// Extension method.
internal static void Invoke(this Control control, Action action) {
control.Invoke(action);
}
// Code elsewhere.
this.Invoke(() => {
string myString = controlOut.Name;
});
C# - How do you access information in form controls from a backgroundworker thread
The elegant way of doing this is to create a list of only the data (such as directories) you are interested in and pass it to the BackgroundWorker's DoWorkEventArgs
.
You should never pass Forms controls to a BackgroundWorker; doing that can cause cross-thread exceptions, crash your UI, and cause race conditions as both the UI and worker try to use the same data. Only pass the data you actually need to another thread.
Related Topics
Binding Listbox to List<Object> in Winforms
Objects in Scene Dark After Calling Loadscene/Loadlevel
Why Func<T,Bool> Instead of Predicate<T>
Programmatically Get the Version Number of a Dll
Convert String to Hex-String in C#
Should You Declare Methods Using Overloads or Optional Parameters in C# 4.0
How to Serialize an Exception Object in C#
Graphics.Drawstring VS Textrenderer.Drawtextwhich Can Deliver Better Quality
Webbrowser Documentcompleted Event Fired More Than Once
What Is the JSON.Net Equivalent of Xml's Xpath, Selectnodes, Selectsinglenode
Parse Datetime in Multiple Formats
Overloading Getter and Setter Causes a Stack Overflow in C#
What's the Difference Between Iequatable and Just Overriding Object.Equals()
How to Write Asynchronous Linq Query
Getting the "Diff" Between Two Arrays in C#
How to Return a Custom Http Status Code from a Wcf Rest Method