原谅我,我正在学习C#和面向对象的编程。我正在运行两个线程。线程#2调用不同的类方法。此方法分配对象的数据值。线程#1未成功尝试访问线程#2分配的对象的数据值。线程#1中对象的数据值为空。如何访问此对象及其分配的所有数据值?我基本上想要从Thread#2类保存数据变量并从Thread#1类访问它们。它似乎是一个对象,当我离开该类然后尝试访问Thread#1类中的同一对象时,它在Thread#2类中生成的数据成员值为null。我仍然可以在我的示例中保存实例化的对象值,还是应该将事物声明为静态?下面是我的一些代码来说明我的问题。感谢任何可以推荐或说明如何解决此问题的人。
// 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
}
}
答案 0 :(得分:3)
你的2个主题各自构成Lru_SetChanFreq
的实例。这2个实例不相关或耦合。在一个线程(SetChanFreq.SetFreq()
)上设置值与另一个线程无关。
几点:
Lru_
这样的前缀会对可读性产生负面影响。 答案 1 :(得分:0)
您的问题是您正在初始化并访问两个线程中的不同Lru_SetChanFreq
个实例。您应该只初始化一个,将其分配给类字段,然后从另一个线程访问同一个实例。以下是您的代码的精简版本:
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();
}
}
更新:我编辑了我的代码以引入正确的线程同步(以替换OP的while (LruListenThread.IsAlive)
和Thread.Sleep(1)
)。这包括三个部分:
ManualResetEvent
实例。 WaitOne
,以使其等待。 Set
后,从线程2调用Lru_SetChanFreq
,从而向线程1发出信号,告知它可以继续。