C#在Thread中设置变量

时间:2014-11-06 16:55:12

标签: c# .net multithreading network-programming threadpool

我正在尝试使用Threads进行私有项目,我有一个问题,因为我觉得很容易回答。

是否可以在另一个线程中设置变量?

这里有一个小代码示例,向您展示我正在尝试做的事情:

public class PartyClass
{
     public boolean partytime = true;

     public void MakeParty()
     {
          while(partytime)
               Console.WriteLine("I'm making a party here");

          Console.WriteLine("The party ended. Please leave now");
     }

     public void StopParty()
     {
          partytime = false;
     }
}

public class MainThread
{
     public static int Main(String[] args)
     {
          PartyClass party = new PartyClass();
          Thread partyThread = new Thread(new ThreadStart(party.MakeParty()));
          partyThread.Start();
          while (!partyThread.IsAlive) ;

          System.Threading.Thread.Sleep(5000);

          // Now I want to somehow call the StopParty() Method
     }
}

我不知道我想要做的事情是否真的很愚蠢,但我认为这是一种以干净的方式阻止“Partythread”的好方法。

这可能还是有更好的解决方案? 谢谢你的想法。

(我没有测试代码 - 只是把它写出来了)

3 个答案:

答案 0 :(得分:1)

您可以像调用start方法一样调用stop方法:

party.StopParty();

为了确保不仅缓存在另一个线程中所做的更改,partytime字段也应标记为volatile

答案 1 :(得分:1)

您应该使用同步工具,例如CancellationToken

您的代码如下:

public class PartyClass
{
    private readonly CancellationToken _cancellationToken;

    public PartyClass(CancellationToken cancellationToken)
    {
        _cancellationToken = cancellationToken;
    }

    public void MakeParty()
    {
        while (!_cancellationToken.IsCancellationRequested)
            Console.WriteLine("I'm making a party here");

        Console.WriteLine("The party ended. Please leave now");
    }
}

public class MainThread
{
    public static int Main(String[] args)
    {
        var cancellationSource = new CancellationTokenSource();
        PartyClass party = new PartyClass(cancellationSource.Token);
        Thread partyThread = new Thread(party.MakeParty);
        partyThread.Start();

        System.Threading.Thread.Sleep(5000);

        cancellationSource.Cancel();

        partyThread.Join();
    }
}

它是线程安全的,不仅适用于此,而且适用于更高级的场景,以及处理任务。

答案 2 :(得分:0)

如果想要更多线程来请求相同的变量,请注意线程同步问题(当两个线程尝试访问同一个变量时)。

我将展示最安全的方式(可能比你需要的更多)。最好的方法是声明一个静态对象来设置lock,以确保你有一个线程一次更改聚会标志。

public class PartyClass
{

    private object _partyTimeLock = new Object();  // executed at class init
    private boolean partyTime= true;

    public bool IsPartyGoingOn()
    {
       bool itIsGoingOn = false;
       lock(_partyTimeLock) {
          itIsGoingOn = partyTime;
       }
       return itIsGoingOn;
    }

    public void StopParty()
    {
        lock(_partyTimeLock) {
           partyTime = false;
        }
    }

    public void MakeParty()
    {
         while(IsPartyGoingOn()) {
              Console.WriteLine("I'm making a party here");
         }

         Console.WriteLine("The party ended. Please leave now");
    }
}

在这个例子中,无论谁试图调用IsPartyGoingOn(),你都不会有问题(无论是类自己的线程还是其他线程)。 lock关键字可以保证您正确行事。