加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 线程同步打印字符串

发布时间:2020-12-15 23:22:32 所属栏目:百科 来源:网络整理
导读:我写了一个小程序,打
我写了一个小程序,打印“x”,然后是“”,然后再打印“x”,依此类推.
我的想法是让它在两个线程中运行,以便第一个线程打印“x”,第二个线程打印“”.输出如下所示:
“x” – >线程号1
“” – >线程号2
“x” – >线程编号1enter代码在这里
“” – >线程号2
等等..

我写的内容似乎工作正常,但在我看来它是写的
非常老式的方式:

public class Example
 {
    private static int count = 10;
    private static int i = 0;
    private static bool isOneActive = false;


  private static void Run1(object o)
  {
      string s = o as string;

      while(true)
      {
          if (!isOneActive)
          {
              Console.WriteLine("Hello from thread number: " +   
                      Thread.CurrentThread.ManagedThreadId + " -> " + s);
              isOneActive = true;
              if (i++ > count) break;
          }
      }
  }

  private static void Run2(object o)
  {
      string s = o as string;

      while(true)
      {
          if (isOneActive)
          {
              Console.WriteLine("Hello from thread number: " + 
                Thread.CurrentThread.ManagedThreadId + " -> " + s);
              isOneActive = false;
              if (i++ > count) break;
          }
      }
  }

  static void Main()
  {
      Thread t1 = new Thread(Run1);
      Thread t2 = new Thread(Run2);
      t1.Start("x");
      t2.Start("+");
  }

我知道现在.NET有许多用于线程同步的工具,例如ManualResetEvent类和Task库.那么我们如何使用ManualResetEvent类编写相同的程序呢?有可能吗?

解决方法

你的代码不仅老式,效率很低.它无缘无故地旋转,只能等待;这应该尽可能避免被称为 Busy wait.

更好的方法是使用评论中提到的Waithandles.

一个简单的实现,代码变化很小,如下所示.

public class Example
{
    private static int count = 10;
    private static int i = 0;
    private static AutoResetEvent firstEvent = new AutoResetEvent(true);
    private static AutoResetEvent secondEvent = new AutoResetEvent(false);


    private static void Run1(object o)
    {
        string s = o as string;

        while (true)
        {
            firstEvent.WaitOne();
            Console.WriteLine("Hello from thread number: " + Thread.CurrentThread.ManagedThreadId + " -> " + s);
            secondEvent.Set();
            if (Interlocked.Increment(ref i) > count)
                break;
        }
    }

    private static void Run2(object o)
    {
        string s = o as string;

        while (true)
        {
            secondEvent.WaitOne();
            Console.WriteLine("Hello from thread number: " + Thread.CurrentThread.ManagedThreadId + " -> " + s);
            firstEvent.Set();
            if (Interlocked.Increment(ref i) > count)
                break;
        }
    }

    static void Main()
    {
        Thread t1 = new Thread(Run1);
        Thread t2 = new Thread(Run2);
        t1.Start("x");
        t2.Start("+");
    }
}

请注意,firstEvent是在initialState标志设置为true的情况下实例化的,这意味着第一个线程最初不会等待.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读