2017-10-31 28 views
0

これがC++の場合は、ポインタを使用します。私はC#の構文に苦しんでいて、これを解決する方法がわからないほど新しくなっています。Main()とスレッドproc(別のクラス)の同じ変数にアクセスする方法は?

この例では、別のクラスのスレッドからアクセスしたい "ProgramDat"という名前の "Program"クラスにメンバー変数があります。さらに、スレッドがそのメモリ位置を変更できるようにし、Program :: Main()に変数とProgram :: Main()と同様に更新を見て、スレッドに参照させます。

refはしていないようです。私が使うことができる別の構造がありますか?

(そして、私は私がこの記事を簡単にするために任意の同期技術を残しました。ここでは潜在的な競合状態を認識しています。)

感謝。

.NETで
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

メインは静的で、変数は同じである必要があります。 Programクラスでは、ProgramDatをpublic(またはinternal)とし、MyThreadではMyThreadDat = Program.ProgramDatを使用します。 – Rob

+2

'int'は値型ですが、代入は常に値のコピーを作成します。 MyThreadDatの変更は反映されません。それを 'class'の中にラップすることを検討してください。あなたは本当に本当に本当にスレッディングを読む必要があります。この種のコードはあなたをひどく傷つけるでしょう。同期を理解することが非常に重要です。 –

答えて

1

ほとんどのタイプは、ちょうどC/C++(:列挙型と構造体の主な例外は値型である)内のポインタのような参照セマンティクスを持つ参照型です。

この場合、ProgramDatinternalとし、他のタイプが同じアセンブリ内にある限り、他のタイプの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 
} 
関連する問題