Глобальная переменная не инициализируется в новом потоке - PullRequest
1 голос
/ 23 февраля 2012

Я пытался использовать volatile ....

q - это глобальная переменная класса, к которой должны иметь доступ все члены класса.Должен ли я создать поток т;в классе А?

class A
{
    string q;
    public void SomeMethod ()
    { 
         new Thread(Method ()).Start();

         Console.WriteLine (q);   //this writes out nothing
    }
    private void Method ()
    { 
         q = "Hello World";
    }
}

Ответы [ 3 ]

4 голосов
/ 23 февраля 2012

Основной поток, который выполняет Console.WriteLine(q), выполняет эту строку и завершает работу до того, как у нового потока, который вы запустили, есть шанс установить значение переменной.

Проведите некоторое исследование по синхронизации потоков.

1 голос
/ 23 февраля 2012

Попробуйте (обратите внимание, что ваш мозг понимает причину, по которой ваш код не работает. Это НЕ предложение для шаблона - спасибо за комментарий, Крис):

class A 
{ 
  string q; 
  public void SomeMethod () 
  {  
    new Thread(Method ()).Start(); 
    //Add this so the thread finishes (not a good permanent solution)
    Thread.Sleep(500);
    Console.WriteLine (q);   //this writes out nothing 
  } 
  private void Method () 
  {  
    q = "Hello World"; 
  } 
} 

Почемуэто сработает?Потому что это дает первому потоку возможность закончить свою работу перед тем, как писать в консоль.Это означает, что один поток пишет, а другой настраивает.

Теперь, лучший способ - заблокировать переменную при изменении / получении q.Простая блокировка подойдет в этом примере.Просто заблокируйте переменную как при установке, так и при извлечении для записи в консоль.

0 голосов
/ 23 февраля 2012

Вы не блокируете выполнение, чтобы дождаться запуска нового потока. Если вы просто хотите, чтобы он что-то записывал, вы можете использовать waitHandle или действительно простой логический флаг, подобный этому:

class A 
{ 
string q; 
bool hasBeenSet;
public void SomeMethod () 
{  
     new Thread(Method ()).Start(); 

     while(!hasBeenSet)
     {
       Thread.Sleep(10);
     }

     Console.WriteLine (q);   //this writes out nothing 
} 
private void Method () 
{  
     q = "Hello World"; 
     hasBeenSet = true;
} 
} 

Несмотря на это, вам действительно следует провести некоторое исследование WaitHandles и объектов / шаблонов синхронизации.

...