This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
The calling thread cannot access this object because a different thread owns it
Error:
The calling thread cannot access this object because a different thread owns it.
Code:
public partial class MainWindow : Window
{
Thread t;
bool interrupt;
public MainWindow()
{
InitializeComponent();
}
private void btss_Click(object sender, RoutedEventArgs e)
{
if (t == null)
{
t = new Thread(this.calculate);
t.Start();
btss.Content = "Stop";
}
else
{
t.Interrupt();
}
}
private void calculate()
{
int currval = 2;
int devide = 2;
while (!interrupt)
{
for (int i = 2; i < currval/2; i++)
{
if (2 % i != 0)
{
lbPrimes.Items.Add(currval.ToString()); //Error occures here
}
}
currval++;
}
}
}
What would be causing this, and how can I resolve it?
You need to rejoin the main UI thread in order to affect the UI. You can check whether this is needed with InvokeRequired, and implement Invoke before referencing the controls.
private void calculate()
{
if (InvokeRequired)
{
Invoke(new Action(() => calculate()));
}
else
{
//
}
}
Accessing any UI element (lblPrimes here) from a non-UI thread is not allowed. You have to use Invoke from your thread to do that.
Here is a good tutorial:
http://weblogs.asp.net/justin_rogers/pages/126345.aspx
You can only update the GUI from the main thread.
In your worker method (calculate()) you are trying to add items to a listbox.
lbPrimes.Items.Add(currval.ToString());
This causes the exception.
You are accessing the control in a manner that is not thread safe. When a thread that did not create the control tries to call it, you'll get an InvalidOperationException.
If you want to add items to the listbox you need to use InvokeRequired as TheCodeKing mentioned.
For example:
private delegate void AddListItem(string item);
private void AddListBoxItem(string item)
{
if (this.lbPrimes.InvokeRequired)
{
AddListItem d = new AddListItem(item);
this.Invoke(d, new object[] { item});
}
else
{
this.lbPrimes.Items.Add(item);
}
}
Call this AddListBoxItem(...) method within your Calculate() method instead of directly trying to add items to the listbox control.
The problem is that your worker thread is attempting to access a UI element which is not allowed. The exception you are getting is warning you about this. Often times you do not even get that. Instead your application will fail unpredictably and spectacularly.
You could use Control.Invoke to marshal the execution of a delegate onto the UI thread. This delegate would perform the lbPrimes.Items.Add operations. However, I do not recommend this approach in this case. The reason is because it will slow down the worker thread.
My preferred solution would be to have the worker thread add currval to a ConcurrentQueue. Then the UI thread will periodically poll this collection via a System.Windows.Forms.Timer to dequeue the values and place them in the ListBox. This has a lot of advantages over using Control.Invoke.
It removes the tight coupling between the worker and UI threads that Invoke imposes.
It puts the responsibility of updating the UI in the UI thread where it should belong anyway.
The UI thread gets to dictate when and how often the update takes place.
The worker thread does not have to wait for the UI to respond to the Invoke request. It will increase the throughput on the worker thread.
It is more efficient since Invoke is costly operation.
Many of the subtle race conditions that arise when attempting to a terminate a worker thread using Invoke naturally go away.
Here is how my preferred option might look.
private void calculate()
{
int currval = 2;
int devide = 2;
while (!interrupt)
{
for (int i = 2; i < currval/2; i++)
{
if (2 % i != 0)
{
queue.Add(currval); // ConcurrentQueue<int>
}
}
currval++;
}
}
private void Timer_Tick(object sender, EventArgs args)
{
int value;
while (queue.TryDequeue(out value))
{
lbPrimes.Items.Add(value.ToString());
}
}
I noticed a couple of other problems.
Thread.Interrupt unblocks the BCL waiting calls like WaitOne, Join, Sleep, etc. Your usage of it serves no purpose. I think what you want to do instead is set interrupt = true.
You should probably interrupt in the for loop instead of the while loop. If currval gets big enough it will take longer and longer for the thread to respond to the interrupt request.
Working in Winforms with C#, I have a main form that creates a second UI form on a separate thread.
viewThread = new Thread( ( ) =>
{
views = new Views.Views( displayRotators, screenLocationLeft, screenLocationTop, screenHeight, screenWidth );
Application.Run( views );
} );
viewThread.SetApartmentState( ApartmentState.STA );
viewThread.Start( );
On the second UI form, I now need to invoke a method to start a display loop that will run until I terminate the thread. I've spent about three hours trying to find a way to do this, but all I can find are examples of calling methods on the main UI thread from the worker thread, not calling methods on the worker thread FROM the main UI thread. Can anyone tell me how I can do this?
Thanks.
There are very few cases where running multiple UI threads really makes sense. Unless you have a very compelling reason to do that, I would go back to a single UI thread.
Assuming you must have multiple UI threads, the golden rule is that Controls may only be updated from the UI thread they were created on.. If you want to call methods in general, you do not have to marshal them at all. However, if those methods in turn interact with a UI control, you would just marshal that call exactly the same way you would if the call were from any other thread that is not the UI thread belonging to the control.
If you might have something like
btnOnForm1OnUIThread1_Click(...)
{
UpdateForm2OnUIThread2();
}
UpdateForm2OnUIThread2()
{
if (control.InvokeRequired)
{
// Syntax of this line may be slightly off as I'm writing from memory ...
// I normally use an extension method
control.Invoke(UpdateForm2OnUIThread2);
}
else
{
control.Text = "Blah";
}
}
a. there is nothing wrong with using multiple UI threads if you know what you do.
b. it is incorrect and confusing calling a UI thread worker - UI thread #2 is same as #1
from the developer standspoint. once you realize it - many problem will clear themselves.
c. if you want to call view2.SomeMethod() [run in UI thread #2] from view1 [run in UI thread #1] - call BeginInvoke on the view2.
The code below is simple to adopt. button1 - launches the second UI thread. button2 - calls method from UI thread 1 on the form which is in UI thread 2
Form2 form;
private void button1_Click(object sender, EventArgs e)
{
Thread viewThread = new Thread(() =>
{
form = new Form2();
Application.Run(form);
});
viewThread.SetApartmentState(ApartmentState.STA);
viewThread.Start();
label1.Text = Thread.CurrentThread.ManagedThreadId.ToString();
}
private void button2_Click(object sender, EventArgs e)
{
if (form != null)
{
form.BeginInvoke(new Action(() =>
{form.Method("Form1 is calling...");}));
}
}
in the form 2 :
public void Method(string s)
{
label1.Text = string.Format("{0} '{1}'",
Thread.CurrentThread.ManagedThreadId, s);
}
you will see that the thread number is different and yet the string has crossed them OK.
I have a c# .NET winforms app making this async call:
simpleDelegate.BeginInvoke(null, null);
My function is being called by the delegate and that all works great. The problem is, after the function finishes on the worker thread, I need the main thread to update some controls on my winform. If the worker thread tries to update these controls, .NET freaks out. But I need the main thread to remain responsive to user actions, and then call my function UpdateFormAfterServerCall() ONLY AFTER the worker thread finishes calling the async function.
I would greatly appreciate if you can give me a concise code sample, rather than abstractly explain how to do this. I've read a hundred explanations already, and am just having trouble wiring it together correctly.
Note: Before the BeginInvoke I have:
simpleDelegate = new MethodInvoker(CallServer);
From different thread if you want to update GUI which is owned by another thread use MethodInvoker
if(control.InvokeRequired)
control.Invoke( (MethodInvoker) ( ()=> updating_function() ) );
else
updating_function();
You could use a BackgroundWorker:
BackgroundWorker bw = new BackgroundWorker();
string result = null;
bw.DoWork += (s, e) =>
{
// Executes on background thread.
// UI remains responsive to user activity during this time.
result = CallServer();
};
bw.RunWorkerCompleted += (s, e) =>
{
// Executes on UI thread upon completion.
resultTextBox.Text = result;
};
bw.RunWorkerAsync();
The Control class (Form is a Control as well) has an Invoke method, you can call this from any thread to execute code on the GUI thread.
In addition, Control has a convenient InvokeRequired property that informs you whether you are on the GUI thread already. You could for instance create the following method in your form:
public class MyForm
{
// ...
public void UpdateMe()
{
if (InvokeRequired)
{
Invoke(new Action(UpdateMe));
return;
}
// Code to update the control, guaranteed to be on the GUI thread
}
}
Here is the code sample [what you want exactly] -
http://www.yoda.arachsys.com/csharp/threads/winforms.shtml
& you can read about all flavours of async here -
http://msdn.microsoft.com/en-us/library/2e08f6yc(v=vs.100).aspx
I am currently writing my first program on C# and I am extremely new to the language (used to only work with C so far). I have done a lot of research, but all answers were too general and I simply couldn't get it t work.
So here my (very common) problem:
I have a WPF application which takes inputs from a few textboxes filled by the user and then uses that to do a lot of calculations with them. They should take around 2-3 minutes, so I would like to update a progress bar and a textblock telling me what the current status is.
Also I need to store the UI inputs from the user and give them to the thread, so I have a third class, which I use to create an object and would like to pass this object to the background thread.
Obviously I would run the calculations in another thread, so the UI doesn't freeze, but I don't know how to update the UI, since all the calculation methods are part of another class.
After a lot of reasearch I think the best method to go with would be using dispatchers and TPL and not a backgroundworker, but honestly I am not sure how they work and after around 20 hours of trial and error with other answers, I decided to ask a question myself.
Here a very simple structure of my program:
public partial class MainWindow : Window
{
public MainWindow()
{
Initialize Component();
}
private void startCalc(object sender, RoutedEventArgs e)
{
inputValues input = new inputValues();
calcClass calculations = new calcClass();
try
{
input.pota = Convert.ToDouble(aVar.Text);
input.potb = Convert.ToDouble(bVar.Text);
input.potc = Convert.ToDouble(cVar.Text);
input.potd = Convert.ToDouble(dVar.Text);
input.potf = Convert.ToDouble(fVar.Text);
input.potA = Convert.ToDouble(AVar.Text);
input.potB = Convert.ToDouble(BVar.Text);
input.initStart = Convert.ToDouble(initStart.Text);
input.initEnd = Convert.ToDouble(initEnd.Text);
input.inita = Convert.ToDouble(inita.Text);
input.initb = Convert.ToDouble(initb.Text);
input.initc = Convert.ToDouble(initb.Text);
}
catch
{
MessageBox.Show("Some input values are not of the expected Type.", "Wrong Input", MessageBoxButton.OK, MessageBoxImage.Error);
}
Thread calcthread = new Thread(new ParameterizedThreadStart(calculations.testMethod);
calcthread.Start(input);
}
public class inputValues
{
public double pota, potb, potc, potd, potf, potA, potB;
public double initStart, initEnd, inita, initb, initc;
}
public class calcClass
{
public void testmethod(inputValues input)
{
Thread.CurrentThread.Priority = ThreadPriority.Lowest;
int i;
//the input object will be used somehow, but that doesn't matter for my problem
for (i = 0; i < 1000; i++)
{
Thread.Sleep(10);
}
}
}
I would be very grateful if someone had a simple explanation how to update the UI from inside the testmethod. Since I am new to C# and object oriented programming, too complicated answers I will very likely not understand, I'll do my best though.
Also if someone has a better idea in general (maybe using backgroundworker or anything else) I am open to see it.
First you need to use Dispatcher.Invoke to change the UI from another thread and to do that from another class, you can use events.
Then you can register to that event(s) in the main class and Dispatch the changes to the UI and in the calculation class you throw the event when you want to notify the UI:
class MainWindow : Window
{
private void startCalc()
{
//your code
CalcClass calc = new CalcClass();
calc.ProgressUpdate += (s, e) => {
Dispatcher.Invoke((Action)delegate() { /* update UI */ });
};
Thread calcthread = new Thread(new ParameterizedThreadStart(calc.testMethod));
calcthread.Start(input);
}
}
class CalcClass
{
public event EventHandler ProgressUpdate;
public void testMethod(object input)
{
//part 1
if(ProgressUpdate != null)
ProgressUpdate(this, new YourEventArgs(status));
//part 2
}
}
UPDATE:
As it seems this is still an often visited question and answer I want to update this answer with how I would do it now (with .NET 4.5) - this is a little longer as I will show some different possibilities:
class MainWindow : Window
{
Task calcTask = null;
void buttonStartCalc_Clicked(object sender, EventArgs e) { StartCalc(); } // #1
async void buttonDoCalc_Clicked(object sender, EventArgs e) // #2
{
await CalcAsync(); // #2
}
void StartCalc()
{
var calc = PrepareCalc();
calcTask = Task.Run(() => calc.TestMethod(input)); // #3
}
Task CalcAsync()
{
var calc = PrepareCalc();
return Task.Run(() => calc.TestMethod(input)); // #4
}
CalcClass PrepareCalc()
{
//your code
var calc = new CalcClass();
calc.ProgressUpdate += (s, e) => Dispatcher.Invoke((Action)delegate()
{
// update UI
});
return calc;
}
}
class CalcClass
{
public event EventHandler<EventArgs<YourStatus>> ProgressUpdate; // #5
public TestMethod(InputValues input)
{
//part 1
ProgressUpdate.Raise(this, status); // #6 - status is of type YourStatus
// alternative version to the extension for C# 6+:
ProgressUpdate?.Invoke(this, new EventArgs<YourStatus>(status));
//part 2
}
}
static class EventExtensions
{
public static void Raise<T>(this EventHandler<EventArgs<T>> theEvent,
object sender, T args)
{
if (theEvent != null)
theEvent(sender, new EventArgs<T>(args));
}
}
#1) How to start the "synchronous" calculations and run them in the background
#2) How to start it "asynchronous" and "await it": Here the calculation is executed and completed before the method returns, but because of the async/await the UI is not blocked (BTW: such event handlers are the only valid usages of async void as the event handler must return void - use async Task in all other cases)
#3) Instead of a new Thread we now use a Task. To later be able to check its (successfull) completion we save it in the global calcTask member. In the background this also starts a new thread and runs the action there, but it is much easier to handle and has some other benefits.
#4) Here we also start the action, but this time we return the task, so the "async event handler" can "await it". We could also create async Task CalcAsync() and then await Task.Run(() => calc.TestMethod(input)).ConfigureAwait(false); (FYI: the ConfigureAwait(false) is to avoid deadlocks, you should read up on this if you use async/await as it would be to much to explain here) which would result in the same workflow, but as the Task.Run is the only "awaitable operation" and is the last one we can simply return the task and save one context switch, which saves some execution time.
#5) Here I now use a "strongly typed generic event" so we can pass and receive our "status object" easily
#6) Here I use the extension defined below, which (aside from ease of use) solve the possible race condition in the old example. There it could have happened that the event got null after the if-check, but before the call if the event handler was removed in another thread at just that moment. This can't happen here, as the extensions gets a "copy" of the event delegate and in the same situation the handler is still registered inside the Raise method.
I am going to throw you a curve ball here. If I have said it once I have said it a hundred times. Marshaling operations like Invoke or BeginInvoke are not always the best methods for updating the UI with worker thread progress.
In this case it usually works better to have the worker thread publish its progress information to a shared data structure that the UI thread then polls at regular intervals. This has several advantages.
It breaks the tight coupling between the UI and worker thread that Invoke imposes.
The UI thread gets to dictate when the UI controls get updated...the way it should be anyway when you really think about it.
There is no risk of overrunning the UI message queue as would be the case if BeginInvoke were used from the worker thread.
The worker thread does not have to wait for a response from the UI thread as would be the case with Invoke.
You get more throughput on both the UI and worker threads.
Invoke and BeginInvoke are expensive operations.
So in your calcClass create a data structure that will hold the progress information.
public class calcClass
{
private double percentComplete = 0;
public double PercentComplete
{
get
{
// Do a thread-safe read here.
return Interlocked.CompareExchange(ref percentComplete, 0, 0);
}
}
public testMethod(object input)
{
int count = 1000;
for (int i = 0; i < count; i++)
{
Thread.Sleep(10);
double newvalue = ((double)i + 1) / (double)count;
Interlocked.Exchange(ref percentComplete, newvalue);
}
}
}
Then in your MainWindow class use a DispatcherTimer to periodically poll the progress information. Configure the DispatcherTimer to raise the Tick event on whatever interval is most appropriate for your situation.
public partial class MainWindow : Window
{
public void YourDispatcherTimer_Tick(object sender, EventArgs args)
{
YourProgressBar.Value = calculation.PercentComplete;
}
}
You're right that you should use the Dispatcher to update controls on the UI thread, and also right that long-running processes should not run on the UI thread. Even if you run the long-running process asynchronously on the UI thread, it can still cause performance issues.
It should be noted that Dispatcher.CurrentDispatcher will return the dispatcher for the current thread, not necessarily the UI thread. I think you can use Application.Current.Dispatcher to get a reference to the UI thread's dispatcher if that's available to you, but if not you'll have to pass the UI dispatcher in to your background thread.
Typically I use the Task Parallel Library for threading operations instead of a BackgroundWorker. I just find it easier to use.
For example,
Task.Factory.StartNew(() =>
SomeObject.RunLongProcess(someDataObject));
where
void RunLongProcess(SomeViewModel someDataObject)
{
for (int i = 0; i <= 1000; i++)
{
Thread.Sleep(10);
// Update every 10 executions
if (i % 10 == 0)
{
// Send message to UI thread
Application.Current.Dispatcher.BeginInvoke(
DispatcherPriority.Normal,
(Action)(() => someDataObject.ProgressValue = (i / 1000)));
}
}
}
Everything that interacts with the UI must be called in the UI thread (unless it is a frozen object). To do that, you can use the dispatcher.
var disp = /* Get the UI dispatcher, each WPF object has a dispatcher which you can query*/
disp.BeginInvoke(DispatcherPriority.Normal,
(Action)(() => /*Do your UI Stuff here*/));
I use BeginInvoke here, usually a backgroundworker doesn't need to wait that the UI updates. If you want to wait, you can use Invoke. But you should be careful not to call BeginInvoke to fast to often, this can get really nasty.
By the way, The BackgroundWorker class helps with this kind of taks. It allows Reporting changes, like a percentage and dispatches this automatically from the Background thread into the ui thread. For the most thread <> update ui tasks the BackgroundWorker is a great tool.
If this is a long calculation then I would go background worker. It has progress support. It also has support for cancel.
http://msdn.microsoft.com/en-us/library/cc221403(v=VS.95).aspx
Here I have a TextBox bound to contents.
private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Debug.Write("backgroundWorker_RunWorkerCompleted");
if (e.Cancelled)
{
contents = "Cancelled get contents.";
NotifyPropertyChanged("Contents");
}
else if (e.Error != null)
{
contents = "An Error Occured in get contents";
NotifyPropertyChanged("Contents");
}
else
{
contents = (string)e.Result;
if (contentTabSelectd) NotifyPropertyChanged("Contents");
}
}
You are going to have to come back to your main thread (also called UI thread) in order to update the UI.
Any other thread trying to update your UI will just cause exceptions to be thrown all over the place.
So because you are in WPF, you can use the Dispatcher and more specifically a beginInvoke on this dispatcher. This will allow you to execute what needs done (typically Update the UI) in the UI thread.
You migh also want to "register" the UI in your business, by maintaining a reference to a control/form, so you can use its dispatcher.
Thank God, Microsoft got that figured out in WPF :)
Every Control, like a progress bar, button, form, etc. has a Dispatcher on it. You can give the Dispatcher an Action that needs to be performed, and it will automatically call it on the correct thread (an Action is like a function delegate).
You can find an example here.
Of course, you'll have to have the control accessible from other classes, e.g. by making it public and handing a reference to the Window to your other class, or maybe by passing a reference only to the progress bar.
Felt the need to add this better answer, as nothing except BackgroundWorker seemed to help me, and the answer dealing with that thus far was woefully incomplete. This is how you would update a XAML page called MainWindow that has an Image tag like this:
<Image Name="imgNtwkInd" Source="Images/network_on.jpg" Width="50" />
with a BackgroundWorker process to show if you are connected to the network or not:
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
public partial class MainWindow : Window
{
private BackgroundWorker bw = new BackgroundWorker();
public MainWindow()
{
InitializeComponent();
// Set up background worker to allow progress reporting and cancellation
bw.WorkerReportsProgress = true;
bw.WorkerSupportsCancellation = true;
// This is your main work process that records progress
bw.DoWork += new DoWorkEventHandler(SomeClass.DoWork);
// This will update your page based on that progress
bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
// This starts your background worker and "DoWork()"
bw.RunWorkerAsync();
// When this page closes, this will run and cancel your background worker
this.Closing += new CancelEventHandler(Page_Unload);
}
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
BitmapImage bImg = new BitmapImage();
bool connected = false;
string response = e.ProgressPercentage.ToString(); // will either be 1 or 0 for true/false -- this is the result recorded in DoWork()
if (response == "1")
connected = true;
// Do something with the result we got
if (!connected)
{
bImg.BeginInit();
bImg.UriSource = new Uri("Images/network_off.jpg", UriKind.Relative);
bImg.EndInit();
imgNtwkInd.Source = bImg;
}
else
{
bImg.BeginInit();
bImg.UriSource = new Uri("Images/network_on.jpg", UriKind.Relative);
bImg.EndInit();
imgNtwkInd.Source = bImg;
}
}
private void Page_Unload(object sender, CancelEventArgs e)
{
bw.CancelAsync(); // stops the background worker when unloading the page
}
}
public class SomeClass
{
public static bool connected = false;
public void DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker bw = sender as BackgroundWorker;
int i = 0;
do
{
connected = CheckConn(); // do some task and get the result
if (bw.CancellationPending == true)
{
e.Cancel = true;
break;
}
else
{
Thread.Sleep(1000);
// Record your result here
if (connected)
bw.ReportProgress(1);
else
bw.ReportProgress(0);
}
}
while (i == 0);
}
private static bool CheckConn()
{
bool conn = false;
Ping png = new Ping();
string host = "SomeComputerNameHere";
try
{
PingReply pngReply = png.Send(host);
if (pngReply.Status == IPStatus.Success)
conn = true;
}
catch (PingException ex)
{
// write exception to log
}
return conn;
}
}
For more information: https://msdn.microsoft.com/en-us/library/cc221403(v=VS.95).aspx
References:
http://msdn.microsoft.com/en-us/library/ms171728.aspx
http://stackoverflow.com/questions/5408155/how-to-make-delegate-thread-sta
I wanted to create a new Thread and make it STA therefore I was not able to use asynchronous delegates or BackgroudWorker (as mentioned in references link 1) Therefore I end up creating a Thread of my own make it STA and attach a callback to know when the Task is complete. The code is something like below and even though I am using invoke required, I still get InvalidOperationException (once in a while)
delegate UpdateEventHander(Object sender, EventArgs e);
class MyTask{
// to generate an event
public event UpdateEventHandler Finished;
public void Start(){
Result = // something that require the thread to be STA.
Finished(this, EventArgs.Empty);
}
public Result GetResult(){
return Result;
}
}
Class Foo : Form{
// It has many UI Controls obviously
public void doSomething(){
MyTask task = new MyTask();
task.Finished += new UpdateEventHander(CompletionHandler);
Thread thread = new Thread(new ThreadStart(task.Start));
thread.setAppartmetnState(AppartmentState.STA);
thread.start();
}
public void CompletionHandler(Object sender, EventArgs e){
MyTask task = (MyTask) sender;
if (oneOfMyControls.InvokeRequired){
delegateToUpdateUIconrols del = new delegateToUpdateUIconrols(updateUIControls);
del.invoke();
}else{
UpdateUIControls();
}
}
public delegate void delegateToUpdateUIconrols();
public void UpdateUIControls(){
// It updates UI controls
// Datagrid view value properties like backgroud color and stuff.
// change text in the label.
}
}
Question 1: Which thread will UpdateUIControls execute ? - if you say "Main UI Thread" - then in that case how will the system know if its supposed to run in Main UI thead and NOT some OTHER thread? I am not passing any reference (about Main UI thread) when I call invoke() .. so invoke() is technically executed on the same thread..
Question 2: Once in a while, I get the InvalidOperationException. Exactly this one
http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/6b450a21-e588-414a-afae-9adabfd03674/
If UpdateUIControls is executing in the main UI thread, there should be not prblem, Right? So, I guess answer to my question really depends upon question 1.
I will appreciate if someone share his/her wisdom on this
Karephul
Controls have thread-affinity; you can only safely talk to them from their creating thread.
You are checking InvokeRequired; however, you are mixing up Delegate.Invoke (runs on the current thread) with Control.Invoke (runs on the UI thread); very different meaning. It should be:
oneOfMyControls.Invoke(del [, args]);