如果这是C ++,我会使用指针。我正在努力使用C#语法,而且对于我不知道如何解决这个问题的语言来说已经足够新了。
此示例在“Program”类中有一个名为“ProgramDat”的成员变量,我想从另一个类的线程访问它。另外,我希望线程能够更改该内存位置并让Program :: Main()看到更新以及Program :: Main()更改变量并让线程看到它。
ref似乎没有这样做。我可以使用另一种构造吗?
(我在这里认识到潜在的竞争条件。为了简化这篇文章,我省略了任何同步技术。)
感谢。
using System;
using System.Threading;
public class Program
{
static ManualResetEvent ExitEvent;
static MyThread t;
static int ProgramDat;
public static void Main()
{
ExitEvent = new ManualResetEvent(false);
ProgramDat = 12; // initialize to some value
t = new MyThread(ExitEvent, ref ProgramDat);
Thread.Sleep(1500); // let MyThread run a bit
// Main() doesn't see the changes MyThread::RunLoop() made
Console.WriteLine("Main just before setting to 500, MyFormDat={0}", ProgramDat);
ProgramDat = 500; // and this change is not seen in MyThread::RunLoop();
Console.WriteLine("Main just set MyFormDat={0}", ProgramDat);
Thread.Sleep(2000);
Console.WriteLine("Just prior to telling thread to exit, MyFormDat={0}", ProgramDat);
ExitEvent.Set();
Thread.Sleep(500); // wait to let MyThread::RunLoop() finish
Console.WriteLine("main leaving. MyFormDat={0}", ProgramDat);
}
}
public class MyThread
{
ManualResetEvent e;
Thread t;
int MyThreadDat;
public MyThread(ManualResetEvent ev, ref int FromProgramDat)
{
e = ev;
MyThreadDat = FromProgramDat;
t = new Thread(RunLoop);
t.Start();
}
public void RunLoop()
{
while (true)
{
if (e.WaitOne(300) == true)
{
Console.WriteLine("RunLoop leaving!");
return;
}
else
{
Console.WriteLine("tic. iFormDat={0}", MyThreadDat);
MyThreadDat++; // change it each loop but I can't get Main() to see this change
}
}
}
}
答案 0 :(得分:1)
.NET中的大多数类型都是具有引用语义的引用类型,就像C / C ++中的指针一样(主要的例外是值类型:枚举和结构)。
但在这种情况下,只需创建ProgramDat
internal
,只要其他类型位于同一个程序集中,就可以通过其他类型Program.ProgramDat
访问它。
如果您要分享重要的状态(除非它是不可变的反模式)将其包装在引用类型中,请在Main
中实例化并将引用传递给线程。
NB。 ref
修改更改参数从传递值到按引用传递;这允许被调用函数改变被调用变量的值。
void PassByRef(ref int x) {
x = 42;
}
void PassByValue(int x) {
// This has no effect
x = 84;
}
var Caller() {
x = 1;
Console.WriteLine(x); // Writes 1
PassByRef(ref x);
Console.WriteLine(x); // Writes 42
PassByValue(x);
Console.WriteLine(x); // Writes 42: no change by PassByValue
}