I've a little problem with this code:
This is the "main" method of the app:
private Thread main_process;
private Clases.GestorTR processor;
public void begin()
{
processor = new Clases.GestorTR();
main_process = new Thread(new ThreadStart(processor.ExecuteP));
main_process.Start();
}
I've created a Thread to process other "Transacction Threads" to avoid blocking the GUI.
This is the method ExecuteP, on processor object:
public void ExecuteP()
{
// Readed an DataTable with BD transacction, filled with numbers
foreach (DataRow dr in dtResults.Rows)
{
int Local_number = Convert.toInt32(dr["autonum"].ToString());
ThreadStart starter;
starter = delegate { new QueryBD.QueryCounter(Local_number); };
new Thread(starter).Start();
}
}
This is QueryCounter method of QueryBD class:
....
private void QueryCounter(int _counter)
{
logs.log("ON QUERY_PROCESS: " + _counter);
}
...
Now, the problem. When calling the delegate, some threads are crossing parameters. For example, in the foreach method the log shows correct (1,2,3,4,5,6,7,8) but, in the QueryCounter method (called each time with the new thread, the log shows (1,1,1,4,5,6,6,8) for example. I've also tried to use locks, but the problem is the same. Also testing with the ThreadPool way with the same result.
I think I'm missing something in the foreach loop, because if I debug the first run, the thread is Started, but without action in the log.
Thanks!,
You should try to change some parts of your code like that:
public void ExecuteP()
{
QueryBD facade = new QueryBD.
foreach (DataRow dr in dtResults.Rows)
{
int Local_number = Convert.toInt32(dr["autonum"].ToString());
new Thread(new ParameterizedThreadStart(facade.QueryCounter)).Start(Local_number);
}
}
public void QueryCounter(object _counter)
{
...
}
Hope it works.
Btw. I've created one object called facade and I'm passing that object to various threads. It can also result in some side effects if there will be thread sensitive part of code in the facade object, so you can also consider locking there:
public void QueryCounter(object _counter)
{
lock(this)
{
//
}
}
or providing new QueryBD to each thread, but it can affect performance.
EDIT: Hey, 4 things:
While using ParametrizedThread, the variable passed to Start method of the thread (thread.Start(variable)) is copied at the time of call. Such copied variable is then used in the child thread. Anonymous delegate works different. It keeps the reference to the variable, so when the variable is used by the child thread, it can be changed by the time in your parent thread. That is why you had unpredicted behaviour.
Better explanation you can find here: Differing behavior when starting a thread: ParameterizedThreadStart vs. Anonymous Delegate. Why does it matter?.
The performance depends. If creation of your object is heavy (ex. it creates new connection to DB each time it is created) performance can be seriously affected by creation of many such objects - it is where lock is better. If creation of the object is light, you can create as many objects as you want. It depends.
If you want your code to be run in defined order, you shouldn't use threads at all. If you want to preserve execution order, sequential invoking is the right way - see Hans Passant explanation.
Related
I have written a Window Manager for my program, which keeps certain windows open for the life of the Program (on background threads) (if the user wants them open).
I just implemented an action for the contacts window. The problem is that, the action works when the window is already open, but if the action is invoked when the window isn't open yet, then the window opens, but the action is not carried out (pressing the button again will carry out the action).
the code:
private static SetupContacts _contactsWindow;
private static Thread _contactthread;
public static void ShowContact(repUserObject uo, ContactFormAction action, int contactID)
{
if (_contactsWindow == null)
CreateContactThread(uo, contactID);
// make sure it is still alive
if (!_contactthread.IsAlive)
CreateContactThread(uo, contactID);
if (_contactsWindow != null)
{
_contactsWindow.BringToFront();
_contactsWindow.Focus();
switch (action)
{
case ContactFormAction.ViewContact:
if (contactID > 0)
_contactsWindow.LoadCustomer(contactID); // load the contact
break;
case ContactFormAction.AddNewContact:
_contactsWindow.AddCustomer();
break;
}
}
}
private static void CreateContactThread(repUserObject uo, int contactID)
{
if (_contactthread == null || !_contactthread.IsAlive)
{
_contactthread = new Thread(delegate()
{
_contactsWindow = new SetupContacts(uo, contactID);
_contactsWindow.CerberusContactScreenClosed += delegate { _contactsWindow = null; };
_contactsWindow.CerberusContactHasBeenSaved += delegate(object sender, ContactBeenSavedEventArgs args)
{
if (CerberusContactHasBeenSaved != null)
CerberusContactHasBeenSaved.Raise(sender, args);
};
Application.EnableVisualStyles();
BonusSkins.Register();
SkinManager.EnableFormSkins();
UserLookAndFeel.Default.SetSkinStyle("iMaginary");
Application.Run(_contactsWindow);
});
_contactthread.SetApartmentState(ApartmentState.STA);
_contactthread.Start();
}
}
What happens when the routine runs for the first time, (by calling ShowTime), that it hits the first if statement and goes to CreateContactThread() routine. That does it job, but when it returns, the _contactsWindow is still null. The next time the routine is called (ie, call by pressing the button the second time), it all works fine as the _contactWindow is not null.
How do i get it to do it all in one go ?
I am in vehement agreement with commenter Blorgbeard, who advises that it's a bad idea to run more than one UI thread. The API itself works best when used in a single thread, and many of the kinds of actions and operations one might want to do in code with respect to the UI objects are most easily handled in a single thread, because doing so inherently ensures things happen in the order one expects (e.g. variables are initialized before being used).
That said, if for some reason you really must run your new window in a different thread, you can synchronize the two threads so that the initial thread cannot proceed until the new thread has gotten far enough for the operations you want to perform on the newly-initialized object to have a reasonable chance of success (including, of course, that object having been created in the first place).
There are lots of techniques for synchronizing threads, but I prefer the new TaskCompletionSource<T> object. It's simple to use, and if and when you update the code to use async/await, it will readily mesh with that.
For example:
public static void ShowContact(repUserObject uo, ContactFormAction action, int contactID)
{
CreateContactThread(uo, contactID);
if (_contactsWindow != null)
{
_contactsWindow.BringToFront();
_contactsWindow.Focus();
switch (action)
{
case ContactFormAction.ViewContact:
if (contactID > 0)
_contactsWindow.LoadCustomer(contactID); // load the contact
break;
case ContactFormAction.AddNewContact:
_contactsWindow.AddCustomer();
break;
}
}
}
private static void CreateContactThread(repUserObject uo, int contactID)
{
if (_contactthread == null || !_contactthread.IsAlive)
{
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
_contactthread = new Thread(delegate()
{
_contactsWindow = new SetupContacts(uo, contactID);
_contactsWindow.CerberusContactScreenClosed += delegate { _contactsWindow = null; };
_contactsWindow.CerberusContactHasBeenSaved += delegate(object sender, ContactBeenSavedEventArgs args)
{
if (CerberusContactHasBeenSaved != null)
CerberusContactHasBeenSaved.Raise(sender, args);
};
_contactsWindow.Loaded += (sender, e) =>
{
tcs.SetResult(true);
};
Application.EnableVisualStyles();
BonusSkins.Register();
SkinManager.EnableFormSkins();
UserLookAndFeel.Default.SetSkinStyle("iMaginary");
Application.Run(_contactsWindow);
});
_contactthread.SetApartmentState(ApartmentState.STA);
_contactthread.Start();
tcs.Task.Wait();
}
}
Notes:
You had what appears to me to be redundant checks in your code. The CreateContactThread() method itself checks for null and !IsAlive, and restarts the thread if either of those are false. So in theory, by the time that method returns, the caller should be guaranteed that everything has been initialized as desired. And you should only have to call the method once. So I changed the code to do just that: call the method exactly once, and do so unconditionally (since the method will just do nothing if there is nothing to do).
The calling thread will wait in the CreateContactThread() method after starting the new thread, until the new window's Loaded event has been raised. Of course, the window object itself has been created earlier than that, and you could in fact release the calling thread at that time. But it seems likely to me that you want the window object fully initialized before you start trying to do things to it. So I've delayed the synchronization to that point.
As Blorgbeard has noted, one of the risks of running UI objects in multiple threads is that it's harder to access those objects without getting InvalidOperationExceptions. Even if it works, you should not really be accessing _contactsWindow outside of the thread where it was created, but the code above does just that (i.e. calls BringToFront(), Focus(), LoadCustomer(), and AddCustomer() from the original thread). I make no assurances that the code above is actually fully correct. Only that it addresses the primary synchronization issue that you are asking about.
Speaking of other possible bugs, you probably have an unresolved race condition, in that the new contacts-form thread might be exiting just as you are checking its IsAlive property. If you check the property just before it exits, but then try to access the thread and/or the window after it has exited, your code is likely to do something bad (like crash with an exception). This is yet another example of something that would be a lot easier to address if all of your UI objects were being handled in a single thread.
I admit that some of the above is speculative. It's impossible for me to say for sure how your code will behave without seeing a good, minimal, complete code example. But I feel the likelihood of all of the above being accurate and applicable is very high. :)
So I have a list with 900+ entries in C#. For every entry in the list a method has to be executed, though these must go all at the same time. First I thought of doing this:
public void InitializeThread()
{
Thread myThread = new Thread(run());
myThread.Start();
}
public void run()
{
foreach(Object o in ObjectList)
{
othermethod();
}
}
Now the problem here is that this will execute 1 method at a time for each entry in the list. But I want every single one of them to be running at the same time.
Then I tried making a seperate thread for each entry like this:
public void InitializeThread()
{
foreach(Object o in ObjectList)
{
Thread myThread = new Thread(run());
myThread.Start();
}
}
public void run()
{
while(//thread is allowed to run)
{
// do stuff
}
}
But this seems to give me system.outofmemory exceptions (not a suprise since the list has almost a 1000 entries.
Is there a way to succesfully run all those methods at the same time? Either using multiple threads or only one?
What I'm ultimately trying to achieve is this: I have a GMap, and want to have a few markers on it. These markers represent trains. The marker pops up on the GMap at a certain point in time, and dissappears when it reaches it's destination. All the trains move about at the same time on the map.
If I need to post more of the code I tried please let me know.
Thanks in advance!
What you're looking for is Parallel.ForEach:
Executes a foreach operation on an IEnumerable in which iterations may
run in parallel.
And you use it like this:
Parallel.ForEach(ObjectList, (obj) =>
{
// Do parallel work here on each object
});
I'm moving some code from a winforms control object to a separate object for better modularity. However, there some calls to an external object issuing callbacks, which I have no control of and which can be fired from different threads as the main UI thread. To avoid this I use the well known BeginInvoke scheme to check, whether a call should be transfered to the main UI thread.
When I now move this code to my separated object, I have not necessary a Winforms reference anymore. I could handle over a Control object to still ensure that everything is running in the same thread. But I would rather like to have a generic mechanism which does exactly the same like ensuring, that the Threadconext in which the e.g. the object was created or a specific entry function was called is also used for subsequent calls issued e.g. by external callbacks.
How could this achieved most easily ?
Example:
public class Example
{
ThreadedComponent _Cmp = new ThreadedComponent();
public Example()
{
_Cmp.ThreadedCallback += new ThreadedComponent.CB(Callback);
}
public void StartFunction()
{
// called in ThreadContextA
_Cmp.Start();
}
void Callback(Status s)
{
// is called in ThreadContextB
if(s == SomeStatus)
_Cmp.ContinueFunction(); // must be called in ThreadContextA
}
}
For clarification
ContinueFunction must be called from the same ThreadContext like StartFunction was called. This is not necessarily a UI thread, but at the moment it is of course a button handler.
There is no 'generic' scheme, your class cannot make a lot of assumptions about what thread it is used on and what object can provide the BeginInvoke() method you need. Choose from one of the following options:
Do not help at all, simply document that the event can be raised on a worker thread. Whatever code exists in the GUI layer can of course always figure out how to use BeginInvoke() when needed.
Allow the client code to pass a Control object through your class constructor. You can store it and call its BeginInvoke() method. That works, it isn't terribly pretty because your class now is only usable in a Winforms project.
Expose a property called "SynchronizingObject" of type ISynchronizeInvoke. The GUI layer now has the option to ask you to call ISynchronizeInvoke.BeginInvoke(). Which you do if the property was set, just fire the event directly otherwise. Several .NET Framework classes do this, like Process, FileSystemWatcher, EventLog, etc. It however has the same problem as the previous solution, the interface isn't readily available in a non-Winforms application.
Demand that the client code creates your object on the UI thread. And copy SynchronizationContext.Current in your constructor. You can, later, use its Post() method to invoke. This is the most compatible option, all GUI class libraries in .NET provide a value for this property.
Do keep the trouble in mind when you choose one of the latter bullets. The client code will get the event completely unsynchronized from your thread's code execution. A concrete event handler is somewhat likely to want to access properties on your class to find out more about the state of your class. That state is unlikely to still be valid since your thread has progressed well past the BeginInvoke() call. The client code has no option at all to insert a lock to prevent that from causing trouble. You should strongly consider to not help at all if that's a real issue, it often is.
In C# you cannot assign a thread context to an object, like in Qt for example (C++).
A thread is running in itself, it does not "collect" objects or methods to call them if they were marked somehow.
However synchronizing to a GUI thread in C# is very easy. Instead of the BeginInvoke/Invoke pattern, you can create a System.Windows.Forms.Timer instance, which can call the methods on the non-WinForms objects.
Example:
public interface IMyExternalTask
{
void DoSomething();
}
// ...
List<IMyExternalTask> myTasks = new List<IMyExternalTask>();
System.Windows.Forms.Timer t = new System.Windows.Forms.Timer();
t.Interval = 1000; // Call it every second
t.Tick += delegate(object sender, EventArgs e) {
foreach (var myTask in myTasks)
myTask.DoSomething();
};
t.Start();
In the example your "external" objects must implement the interface, and they can do their tasks from the DoSomething() method, which will be synchronized to the GUI thread.
These external objects don't have to have any reference to any Windows.Forms object.
I solve the problem using a separate queue which runs its own thread. Function Calls are added to the Queue with a Proxyinterface. It's probably not the most elegant way, but it ensures, that everything added to the queue is executed in the queue's threadcontext. This is a very primitive implementation example just to show the basic idea:
public class Example
{
ThreadQueue _QA = new ThreadQueue();
ThreadedComponent _Cmp = new ThreadedComponent();
public Example()
{
_Cmp.ThreadedCallback += new ThreadedComponent.CB(Callback);
_QA.Start();
}
public void StartFunction()
{
_QA.Enqueue(AT.Start, _Cmp);
}
void Callback(Status s)
{
// is called in ThreadContextB
if(s == SomeStatus)
_QA.Enqueue(new ThreadCompAction(AT.Continue, _Cmp);
}
}
public class ThreadQueue
{
public Queue<IThreadAction> _qActions = new Queue<IThreadAction>();
public Enqueue(IThreadAction a)
{
lock(_qActions)
_qActions.Enqueue(a);
}
public void Start()
{
_thWatchLoop = new Thread(new ThreadStart(ThreadWatchLoop));
_thWatchLoop.Start();
}
void ThreadWatchLoop()
{
// ThreadContext C
while(!bExitLoop)
{
lock (_qActions)
{
while(_qActions.Count > 0)
{
IThreadAction a = _qActions.Dequeue();
a.Execute();
}
}
}
}
}
public class ThreadCmpAction : IThreadAction
{
ThreadedComponent _Inst;
ActionType _AT;
ThreadCmpAction(ActionType AT, ThreadedComponent _Inst)
{
_Inst = Inst;
_AT = AT;
}
void Do()
{
switch(AT)
{
case AT.Start:
_Inst.Start();
case AT.Continue:
_Inst.ContinueFunction;
}
}
}
I'm trying to teach myself about threads in C#, and I've run into a problem. Lets say that this is my code:
class MyClass
{
public Queue variable;
internal MyClass()
{
variable = new Queue<int>();
variable.Enqueue(1);
Thread thread = new Thread(new ThreadStart(DoSomething));
thread.IsBackground = true;
thread.Start();
}
public void DoSomething()
{
int i = variable.Dequeue();
MessageBox.Show(i);
}
}
Upon execution I get an exception saying that the queue is empty when I try to dequeue. Debugging shows that the queue is empty within the context of the thread, but not in the larger class. I assume that C# creates thread-local objects for certain things (but not all, if I were to make an int member variable, I could get its value within the thread without any problems) I know java does similiar things, and the way around it is to declare the member variable as "volatile" or something like that. C# has a similiar construct, but I don't think its what I'm looking for (or at least, I used it and it didn't help...) How would I declare a member variable in C# such that any threads created by the class also can access it? (I'd also really like to understand this stuff better, so links to relevant material would be greatly appreciated)
class MyClass {
public Queue variable;
internal MyClass() {
variable = new Queue();
variable.Enqueue(1);
Thread thread = new Thread(new ThreadStart(DoSomething));
thread.IsBackground = true;
thread.Start();
}
public void DoSomething() {
int i = (int)(variable.Dequeue()); //cast required here
//MessageBox may not play nice from non-ui thread
Console.WriteLine(i);
}
}
works fine with only the smallest edit. The queue is visible from the thread. It's not clear how you reached a different conclusion.
You might consider using a generic Queue<int> to avoid the boxing/unboxing associated with storing value types in non-generic collections.
Better yet, you could avoid a whole bunch of noisy thread-synchronization too by using ConcurrentQueue<T>, seeing as you're sharing this queue between threads.
I think you should change these two lines and it should work.
public Queue<int> variable;
MessageBox.Show(i.ToString());
I am trying to learn the threading in C#. Today I sow the following code at http://www.albahari.com/threading/:
class ThreadTest
{
bool done;
static void Main()
{
ThreadTest tt = new ThreadTest(); // Create a common instance
new Thread (tt.Go).Start();
tt.Go();
}
// Note that Go is now an instance method
void Go()
{
if (!done) { done = true; Console.WriteLine ("Done"); }
}
}
In Java unless you define the "done" as volatile the code will not be safe. How does C# memory model handles this?
Guys, Thanks all for the answers. Much appreciated.
Well, there's the clear race condition that they could both see done as false and execute the if body - that's true regardless of memory model. Making done volatile won't fix that, and it wouldn't fix it in Java either.
But yes, it's feasible that the change made in one thread could happen but not be visible until in the other thread. It depends on CPU architecture etc. As an example of what I mean, consider this program:
using System;
using System.Threading;
class Test
{
private bool stop = false;
static void Main()
{
new Test().Start();
}
void Start()
{
new Thread(ThreadJob).Start();
Thread.Sleep(500);
stop = true;
}
void ThreadJob()
{
int x = 0;
while (!stop)
{
x++;
}
Console.WriteLine("Counted to {0}", x);
}
}
While on my current laptop this does terminate, I've used other machines where pretty much the exact same code would run forever - it would never "see" the change to stop in the second thread.
Basically, I try to avoid writing lock-free code unless it's using higher-level abstractions provided by people who really know their stuff - like the Parallel Extensions in .NET 4.
There is a way to make this code lock-free and correct easily though, using Interlocked. For example:
class ThreadTest
{
int done;
static void Main()
{
ThreadTest tt = new ThreadTest(); // Create a common instance
new Thread (tt.Go).Start();
tt.Go();
}
// Note that Go is now an instance method
void Go()
{
if (Interlocked.CompareExchange(ref done, 1, 0) == 0)
{
Console.WriteLine("Done");
}
}
}
Here the change of value and the testing of it are performed as a single unit: CompareExchange will only set the value to 1 if it's currently 0, and will return the old value. So only a single thread will ever see a return value of 0.
Another thing to bear in mind: your question is fairly ambiguous, as you haven't defined what you mean by "thread safe". I've guessed at your intention, but you never made it clear. Read this blog post by Eric Lippert - it's well worth it.
No, it's not thread safe. You could potentially have one thread check the condition (if(!done)), the other thread check that same condition, and then the first thread executes the first line in the code block (done = true).
You can make it thread safe with a lock:
lock(this)
{
if(!done)
{
done = true;
Console.WriteLine("Done");
}
}
Even in Java with volatile, both threads could enter the block with the WriteLine.
If you want mutual exclusion you need to use a real synchronisation object such as a lock.
onle way this is thread safe is when you use atomic compare and set in the if test
if(atomicBool.compareAndSet(false,true)){
Console.WriteLine("Done");
}
You should do something like this:
class ThreadTest{
Object myLock = new Object();
...
void Go(){
lock(myLock){
if(!done)
{
done = true;
Console.WriteLine("Done");
}
}
}
The reason you want to use an generic object, rather than "this", is that if your object (aka "this") changes at all it is considered another object. Thus your lock does not work any more.
Another small thing you might consider is this. It is a "good practices" thing, so nothing severe.
class ThreadTest{
Object myLock = new Object();
...
void Go(){
lock(myLock){
if(!done)
{
done = true;
}
}
//This line of code does not belong inside the lock.
Console.WriteLine("Done");
}
Never have code inside a lock that does not need to be inside a lock. This is due to the delay this causes. If you have lots of threads you can gain a lot of performance from removing all this unnecessary waiting.
Hope it helps :)