Reputation: 59
Forgive me, I'm learning C# and object-oriented programming. I am running two threads. Thread #2 calls a different class method. This method assigns an object's data value. Thread #1 unsuccessfully attempts to access the object's data value that Thread #2 assigned. The object's data value in Thread #1 is null. How do I access this object and all its assigned data values? I basically want to save the data variables from Thread #2 classes and access them from a Thread #1 class. It appears an object and it's data member values generated in a Thread #2 class are null when I leave the class and then try to access the same object in a Thread #1 class. Can I still save the instantiated object values in my example or should I declare things as static? Below is some of my code to illustrate my problem. Thank you for anyone that can recommend or illustrate how to resolve this.
// this is a main operating class that: 1) starts two threads and 2) trys to access the Thread #2 Lru_SetChanFreq class object data from Thread #1 Lru_operations class
public class Lru_operation
{
[STAThread]
static void Main()
{
// starts a separate thread #2
Lru_Listen LruListen1 = new Lru_Listen();
Thread LruListenThread = new Thread(new ThreadStart(LruListen1.ListenForAag));
LruListenThread.Start();
while(!LruListenThread.IsAlive)
;
Thread.Sleep(1);
// follows the main thread #1
Lru_operation LruOpX = new Lru_operation();
LruOpX.LruOperation();
}
// this is where main thread #1 operates
public void LruOperation()
{
// create object to access object data from thread #2 Lru_SetChanFreq class
Lru_SetChanFreq SetChFrq = new Lru_SetChanFreq();
try
{
// do stuff
// ERROR: SetChFrq.LruSetFrq.RxFreq2 = null and then catches an exception to go below.
// Why is this happening if Thread #2 previously sets RxFreq2 = 405.1?
Console.WriteLine("LruSetFrq.RxFreq2 = {0}", SetChFrq.LruSetFrq.RxFreq2);
// do more stuff
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, "connection terminated",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
// this is called from thread #2. It's object is used by thread #1
public class Lru_SetChanFreq
{
#region fields
private string rxFreq2;
private Lru_SetChanFreq mLruSetFrq;
#endregion fields
#region Properties
public Lru_SetChanFreq LruSetFrq
{
get { return mLruSetFrq; }
set { mLruSetFrq = value; }
}
public string RxFreq2
{
get { return rxFreq2; }
set { rxFreq2 = value; Console.WriteLine("rxFreq2 = {0}", rxFreq2); }
}
#endregion Properties
#region methods
public Lru_SetChanFreq()
{
}
public void SetFreq()
{
mLruSetFrq = new Lru_SetChanFreq();
mLruSetFrq.RxFreq2 = "405.1";
// I confirmed that LruSetFrq.RxFreq2 = 405.1
Console.WriteLine("LruSetFrq.RxFreq2 = {0}", LruSetFrq.RxFreq2);
// do stuff
}
#endregion methods
}
// this is starting point of thread #2
public class Lru_Listen
{
#region Fields
// stuff
#endregion Fields
#region Properties
// stuff
#endregion Properties
#region Methods
public void ListenForAag()
{
// do stuff
LruListenAccReq();
}
public void LruListenAccReq()
{
// do stuff
LruShowRequestData(request);
}
public void LruShowRequestData(// stuff )
{
Lru_SetChanFreq SetChanFreq = new Lru_SetChanFreq();
SetChanFreq.SetFreq(); // calls to another class method
}
#endregion Methods
}
}
Upvotes: 0
Views: 366
Reputation: 54897
Your issue is that you are initializing and accessing distinct Lru_SetChanFreq
instances in your two threads. You should initialize just one, assign it to a class field, and then access the same instance from the other thread. Here is a trimmed-down version of your code that does that:
public class Lru_operation
{
[STAThread]
static void Main()
{
Lru_Listen LruListen1 = new Lru_Listen();
// Run LruListen1 on Thread 2
Thread LruListenThread = new Thread(new ThreadStart(LruListen1.ListenForAag));
LruListenThread.Start();
// Wait for its operation to complete
// There is no need to wait for the thread to terminate
LruListen1.readyEvent.WaitOne();
// Read the Lru_SetChanFreq initialized from LruListen1,
// and continue processing it on Thread 1
Lru_operation LruOpX = new Lru_operation();
LruOpX.LruOperation(LruListen1.SetChanFreq);
}
public void LruOperation(Lru_SetChanFreq setChanFreq)
{
// Access the original Lru_SetChanFreq instance received as parameter
}
}
// this is starting point of thread #2
public class Lru_Listen
{
// Declare Lru_SetChanFreq as a field so as to access it externally
internal Lru_SetChanFreq SetChanFreq;
// Our thread synchronization event
internal ManualResetEvent readyEvent = new ManualResetEvent(false);
public void LruShowRequestData(// stuff )
{
this.SetChanFreq = new Lru_SetChanFreq();
SetChanFreq.SetFreq(); // calls to another class method
// Signal that we are ready
readyEvent.Set();
}
}
Update: I've edited my code to introduce proper thread synchronization (to replace the OP's while (LruListenThread.IsAlive)
and Thread.Sleep(1)
). This consists of three parts:
ManualResetEvent
instance that can be accessed by both threads. WaitOne
from Thread 1, in order to make it wait. Set
from Thread 2 once it completes initializing your Lru_SetChanFreq
, thereby signalling to Thread 1 that it may proceed.Upvotes: 0
Reputation: 273621
Your 2 Threads each make an instance of Lru_SetChanFreq
. The 2 instances are not related or coupled. Setting a value on one thread (SetChanFreq.SetFreq()
) has no bearing on the other thread.
A few points:
Lru_
have a negative impact on readability. Upvotes: 3