This question already has answers here:
Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on
(22 answers)
Closed 7 years ago.
it's my first experience with C#, I'm trying to make a progress bar that increases each second on a value (a part of program, it receives current value from another object and sets it to the progress bar).
My simplified object source:
public delegate void LoadingProgressChanged(int percents);
public event LoadingProgressChanged loadingProgressChanged;
public void Enable()
{
loadingTimer = new Timer(1000);
loadingTimer.Elapsed += new ElapsedEventHandler(IncreaseLoadingPercentage);
loadingTimer.Start();
}
private void IncreaseLoadingPercentage(object source, EventArgs e)
{
loadedPercents += getLoadingPercentsPerSecond();
loadingProgressChanged(loadedPercents);
}
Form sources:
In constructor
router.loadingProgressChanged += new AbstractRouter.LoadingProgressChanged(percentageChanged);
Body of percentageChanged
public void percentageChanged(int percs)
{
progressBar1.Value = percs;
}
And I get error
An exception of type 'System.InvalidOperationException' occurred in
System.Windows.Forms.dll but was not handled in user code
Additional information: Cross-thread operation not valid: Control
'progressBar1' accessed from a thread other than the thread it was
created on.
If there is a handler for this exception, the program may be safely
continued.
I understand why it happens: it seems that percentageChanged form is called in timer thread. But how to implement it correctly? Thanks!
Try with something like this:
public void percentageChanged(int percs)
{
Invoke(new Action(() =>
{
progressBar1.Value = percs;
}));
}
Related
This question already has answers here:
Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on
(22 answers)
Closed 1 year ago.
private void browser_LoadingStateChanged(object sender, LoadingStateChangedEventArgs e)
{
addressbar.Text = browser.Address;
}
I have no idea why this is breaking.
When you have multiple threads (UI thread and others), this problem will happen when you want to manipulate an object from a thread, and that object is created by another thread.
You must use Invoke Method:
private void browser_LoadingStateChanged(object sender, LoadingStateChangedEventArgs e)
{
changeAddressBar(browser.Address)
}
void changeAddressBar(string txt){
if (addressbar.InvokeRequired)
addressbar.Invoke(new Action<string>(changeAddressBar), txt);
else
addressbar.Text= txt;
}
This question already has answers here:
How do I create and show WPF windows on separate threads?
(4 answers)
The calling thread cannot access this object because a different thread owns it.WPF [duplicate]
(6 answers)
Closed 2 years ago.
I have an init method in which I create a thread and a window is displayed
This is my application code
public static SplashWindow _splashWindow;
private static ManualResetEvent ResetSplashCreated;
private static Thread SplashThread;
public static void Init(SplashWindow splashWindow)
{
_splashWindow = splashWindow;
ResetSplashCreated = new ManualResetEvent(false);
SplashThread = new Thread(() => ShowSplash(_splashWindow));
SplashThread.SetApartmentState(ApartmentState.STA);
SplashThread.IsBackground = true;
SplashThread.Name = "Splash Screen";
SplashThread.Start();
ResetSplashCreated.WaitOne();
}
public static void ShowSplash(SplashWindow splash)
{
splash.Show();
ResetSplashCreated.Set();
System.Windows.Threading.Dispatcher.Run();
}
now when i call this code:
SplashHelper.Init(new anim());
I get an error in the splash.show(); line
System.InvalidOperationException: 'The calling thread cannot access this object because a different thread owns it.'
You cannot create the window on one thread and Show() it on another.
You will have to both create the thread and call Show() in your ShowSplash method (or on the calling thread).
If you look at the source code of Show, you'll see that the first thing it does is to call a VerifyContextAndObjectState() method.
This method checks whether you are on the thread on which the window was originally created. If you are on another thread, it throws the InvalidOperationException that you are currently getting.
This question already has answers here:
Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on
(22 answers)
Closed 6 years ago.
public partial class JobDataDuplicatorForm : Form
{
public JobDataDuplicatorForm(IJobDataDuplicatorEngine engine)
{
_engine.CopyStartedEvent += GetEventHandler(OnCopyStarted);
_engine.CopyEndedEvent += GetEventHandler(OnCopyEnded);
...
}
private static EventHandler GetEventHandler(Action action)
{
return (sender, args) => action();
}
private void OnCopyStarted()
{
copyStatus.Text = "Copy progress: ";
generateButton.Enabled = false; // Cross-thread operation not valid
}
}
I have the following exception:
Additional information: Cross-thread operation not valid: Control
'generateButton' accessed from a thread other than the thread it was created on.
Can I fix the exception by changing GetEventHandler() instead of wrapping each button in different places like this
Invoke((MethodInvoker)delegate {
generateButton.Enabled = false;
}); ?
How can I do this?
From your comments you said you call JobDataDuplicatorForm(IJobDataDuplicatorEngine engine) from a background thread.
Your class is a Form, any windows controls (Which includes Form) must be initially created on the UI thread or things like Invoke and InvokeRequired break. Whatever code is calling the constructor of JobDataDuplicatorForm must do that call from the UI thread.
This question already has answers here:
Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on
(22 answers)
Closed 7 years ago.
i am developing a code in which a have to read the data form list box and upload an external file, press a button named Start and with this listbox i am getting an error as shown below.
An unhandled exception of type 'System.InvalidOperationException'
occurred in System.Windows.Forms.dll
Additional information: Cross-thread operation not valid: Control
'listBox1' accessed from a thread other than the thread it was created
on.
my code is as follows
private void Start_Click(object sender, EventArgs e)
{
Thread ss = new Thread(Automode);
ss.Start();
}
private void Automode()
{
....
for (int i = 0; i < listBox1.Items.Count; i++)
{
listBox1.SetSelected(i, true);
string pattern = "[gxyzbcmij][-+]?[0-9]*\\.?[0-9]*";
string text = listBox1.Text;
Regex gcode = new Regex(pattern, RegexOptions.IgnoreCase);
MatchCollection code = gcode.Matches(text);
}
.....
}
here at listbox.SetSelected command it is giving an exception as shown above. please suggest the alternate ways to write it.
delegate void SetSelectedCall(int index, bool option);
private void SetSelectedElement(int index, bool option)
{
if (this.listBox1.InvokeRequired)
{
SetSelectedCall d = new SetSelectedCall(SetSelectedElement);
this.Invoke(d, new object[] { int index, bool option});
}
else
{
this.listBox1.SetSelected(index,option);
}
}
Taken from Cross-thread operation not valid: Control 'textBox1' accessed from a thread other than the thread it was created on and tailored for this question.
You can't access the listBox1 from a background thread.
If possible, run the code from the function Automode() directly in the Start_Click method. If you must have the code ran in a background thread, I would perhaps suggest something more like a Task, that way you can still perform the action based on passing arguments and awaiting a response. Then you can still listBox1 items as selected.
This question already has answers here:
Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on
(22 answers)
How to deal with cross-thread access exceptions?
(3 answers)
Closed 9 years ago.
I am setting up a Timer within a method with an interval of 1000 so that every second it will type another corresponding character into a Textbox (pretty much automating typing). When I check for _currentTextLength == _text.Length I get the threading error "The calling thread cannot access this object because a different thread owns it."
public void WriteText(string Text)
{
timer = new Timer();
try
{
_text = Text;
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed_WriteText);
timer.Interval = 1000;
timer.Enabled = true;
timer.Start();
}
catch
{
MessageBox.Show("WriteText timer could not be started.");
}
}
// Write Text Timer Event
void timer_Elapsed_WriteText(object sender, ElapsedEventArgs e)
{
TextBoxAutomationPeer peer = new TextBoxAutomationPeer(_textBox);
IValueProvider valueProvider = peer.GetPattern(PatternInterface.Value) as IValueProvider;
valueProvider.SetValue(_text.Substring(0, _currentTextLength));
if (_currentTextLength == _text.Length) // Error here
{
timer.Stop();
timer = null;
return;
}
_currentTextLength++;
}
The variable _text is a private class variable and so is _currentTextLength. _textBox is self explanatory.
Any way to solve this?
Use a DispatcherTimer instead of a Timer.
A timer that is integrated into the Dispatcher queue which is
processed at a specified interval of time and at a specified priority.
Should solve your problem.
this simply means that you are trying to access some UI element from a thread other then it was created on. To overcome this you need to access it like this
this.Dispatcher.Invoke((Action)(() =>
{
//access it here
}));
Note: If you want to check whether you can access it normally or not you can use this
Dispatcher.CheckAccess