I need to set a flag in a secondary thread started in a form and read it into a method of another form.
How do i could make it?
Printable View
I need to set a flag in a secondary thread started in a form and read it into a method of another form.
How do i could make it?
Use events and a custom delegate with a special parameter (your value).
You can use common property of a class. I suggest you to create your own class for that purpose. If you want to be sure that it is thread safe, use the lock keyword.
For example:
Code:public class Model
{
private object obj;
public object Value
{
get { lock (this) return this.obj; }
set { lock (this) this.obj = value; }
}
}
In general, locking on 'this' is *not* recommended simply because it's too easy to create deadlocks. Also, that's not really threadsafe. It's what you *do* with the 'Value' that matters.Quote:
Originally Posted by boudino
It should be
If the above example, you can have 1,000 threads running the 'ThreadedMethod' but access to the 'Model' object declared at the top is completely threadsafe. The previous example provides no threadsafety in the use of the object.Code:
Model m = new Model(); // All threads can access this model
object locker = new object(); // all threads can access this lock object
public void ThreadedMethod()
{
DoStuff();
lock(locker)
{
DoOperation(m.Value);
DoOtherOperation(m.Value);
}
DoMoreStuff();
}
Maybe you are true, but can you provide a more verbose explanation, please? I don't fully understood you. If I read your sample well, you are locking outside the model, so the m.Value can be still accessed thread unsafe from other code than ThreadedMethod().
In your example, if i call:
object o = m.Value
and then i start using 'o' to do work, every thread can be using 'o' to do work simultaneously. That's the definition of non-threadsafe access ;) If it's ok to be using o in a non-threadsafe way, then that's fine. However since the point of the example was to show how to have threadsafe access, it's not a good example.
Welcome to the world of threaded programming. Every time you want to safely acces m.Value you need to make sure you take out the lock on the same object that other threads will be using.Quote:
If I read your sample well, you are locking outside the model, so the m.Value can be still accessed thread unsafe from other code than ThreadedMethod().
Lets assume m.Value returns a database connection and it can only support 1 simultaenous query at a time. In that case, your code (which just protects the getter and setter) would break horribly as every thread would just use the connection immediately. In my code, every time any thread wants to use the database connection, it must take out the lock on the object, and then it uses the connection. No breakage :)
If I make this:
I Could to instance this class into differents threads and It will work safe?Code:class MyThreadLink
{
private static Boolean bNewState= false;
object locker = new object();
public void SetNewState(Boolean State)
{
lock (locker)
{
bNewSate= State;
}
}
public Boolean ReadState()
{
lock (locker)
{
return bNewSate;
}
}
}
I have not understood this instruction:
What is the namespace for "Model" ?Code:Model m = new Model(); // All threads can access this model
Thanks,
That's not threadsafe.
Go read up on threading and thread safety and read a few tutorials (and do them too). It'll help.
I was demonstrating an example of how you control access to an object, not writing 100% functioning code. In 90%+ of cases you need to control access to the physical object, not controlling access to the getters and setters. Read my previous posts....
Yes, I fell I understand you now. You have solved slightly different task than me, maybe more complex. For clarification: if m.Value would be immutable, than my solution is completely thread-safe, is not it?
or you can simply declare the flag variable as volatile...
Code:public partial class Form1 : Form
{
privat volatile bool _flag = false;
private void ThreadProc() {
_flag = true; // set flag
}
private void SomeMethod() {
while (!_flag) {
// blah blah blah
}
}
}
by the way, what are you trying to accomplish here, if you don't mind? if you're just going to wait for a thread to finish you may use Join().
I used this concept to solve my purpose, Here I handled more than 100 threads
In Form side using InvokeRequired and Invoke I handled It is working fine. May be it will solve the multiple thread problemCode:///
private object locker = new object();
public delegate void EventTable(object sender, clsEventTableArgs e);
public event EventTable evtEventLog;
///
for(int l=0;l<100;l++)
{
Thread tt = new Thread(ThreadedMethod);
tt.Name = l.ToString();
tt.IsBackground = true;
tt.Start(l);
}
public void ThreadedMethod(object lTemp)
{
lock(locker)
{
DoStuff();
DoOperation(m.Value);
DoOtherOperation(m.Value);
DoMoreStuff();
Monitor.PulseAll(locker);
//Here I called raised the custom event to send this thred data to Form,I caught this data in form
clsEventTableArgs args = new clsEventTableArgs(m.Value, (int)lTemp);
evtEventLog(this, args);
}
}
If m.Value is completely immutable, then you don't need 'thead safety' as your object *cannot* change so it is by definition threadsafe.Quote:
Originally Posted by boudino
As for using the volatile keyword, it doesn't make things thread-safe. Thead safety is a hell of a lot more than just protecting access to variables and marking them as volatile.
I didn't think m.Value referene, but the object referenced/returned by m.Value. E.g. if m.Value would be value type rather than reference type. I'll try it explain by example:Quote:
Originally Posted by Mutant_Fruit
In my code, i is local and everything I want is to be sure that it has the value which the another thread could set.Code:Model<int> m = new Model<int>(); // model is implemented the way I've used before
...
m.Value = 20;
// start other thread which is using m and can modify it
// do other job in this thread
int i = m.Value;
Am I still wrong?
It could seem I'm obsedant with this, but I only want to fully understand I see my wrong to learn something new.
I wouldn't do this with an object or by locking on this as Mutant mentioned already.Quote:
Originally Posted by boudino
Here's one thread-safe way to do it.
The bottom line is providing thread safety to a shared variable is simply preventing more than one thread from accessing the variable while a write is occuring.Code:public class Model
{
private string _nameFirst = String.Empty;
private object _nameFirstLock = new object( );
public string NameFirst
{
get { lock (_nameFirstLock) return _nameFirst; }
set { lock (_nameFirstLock) _nameFirst = value; }
}
}
So when m.NameFirst is written to by one thread, and m.NameFirst is read from another thread, you need to only allow one thread access to the variable. This is what the lock statement does (internally it creates a critical section and enters and leaves during the scope of the lock statement).
I have been reviewing some tutorials, I am really a little confused (thanks for the links).
My program has a secondary thread consulting some peripheral (hardware) via comm1, when some event happens, it is created a new record in a SQL table. This thread must set a flag to indicate to a form that there are a new event in order to refresh a datagrid in such a way that the new record appears in screen.