【问题标题】:Console Writeline with threaded C#带有线程 C# 的控制台 Writeline
【发布时间】:2018-01-25 08:51:59
【问题描述】:

您好,我正在尝试为我的控制台应用程序控制台输出创建线程系统。

我就是这样做的 KonsolStream。

public class KonsolStream
{
    ManualResetEvent _pauseEvent = new ManualResetEvent(true);
    ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
    Thread _thread;

    private string _yazi;
    private int _tip;

    public int _Tip
    {
        get => _tip;
        set => _tip = value;
    }
    public string _Yazi
    {
        get => _yazi;
        set => _yazi = value;
    }

    public void KonsolaYaz()
    {
        switch (_Tip)
        {
            case 1:
                //uyarı
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(_Yazi);
                Console.ResetColor();
                IstemciDurdur();
                break;
            case 2:
                //başarı
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine(_Yazi);
                Console.ResetColor();
                IstemciDurdur();
                break;
            case 3:
                //log
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine(_Yazi);
                Console.ResetColor();
                IstemciDurdur();
                break;
            default:
                IstemciDurdur();
                break;
        }
    }
    private void IstemciDurdur()
    {
        _pauseEvent.Reset();
    }
    public void Start()
    {
        _thread = new Thread(DoWork);
        _thread.Start();
    }
    public void Resume()
    {
        _pauseEvent.Set();
    }

    public void DoWork()
    {
        while (true)
        {
            _pauseEvent.WaitOne(Timeout.Infinite);

            if (_shutdownEvent.WaitOne(0))
                break;

            KonsolaYaz();
        }
    }

}
public class KonsolMesaji : KonsolStream
{
    public KonsolMesaji(string yazi,int tip)
    {
        _Yazi = yazi;
        _Tip = tip;
    }
    public void Yaz()
    {
        Start();
    }
}

问题是当我启动 SistemBaslat() 消息不是同步的。 有时它从写消息开始。有时它从再次开始 我想让 KonsolStream 像,当我想向控制台写入一些输出时,我稍后会使用这个流。

【问题讨论】:

  • 欢迎来到多线程的世界。您的消息按照线程执行的顺序写入控制台 - 只是因为您的代码在 SistemBaslat 方法中看起来是线性的,您正在创建线程,一旦您启动线程,您就无法控制各个线程将写入的顺序到控制台。

标签: c# .net multithreading stream console


【解决方案1】:

在阅读您的问题时,我在问自己:您是否只是出于学术原因(即了解登录多线程系统的工作原理)而想了解这一点,还是您实际上想要进行多线程登录以后有生产应用吗?

如果您的答案是后者,我建议您使用log4net,因为只需进行一点配置,您就可以得到您想要的。

更新
再次查看问题后,我同意 PaulF 的观点,即仍然需要将线程的结果绑定在一起,然后将不同的存储桶按顺序写入控制台。 为了实现这一点,您可以使用一个类的(静态)实例,该实例保存每个线程的所有日志消息(为了区分线程,您可以使用线程 id 作为键)并等待线程完成,然后写入该线程的所有日志条目按顺序发送到控制台。

【讨论】:

  • 这不是网络服务器的记录器,那是 apache 的记录器。
  • 因为控制台写入实际上是在 KonsolaYaz 方法的线程中完成的 - 那么 log4net 也会遇到同样的问题。问题是@ErimVarış 认为因为字符串是在构造函数中设置的,并且线程以特定顺序启动,所以线程将以特定顺序处理。不幸的是,一旦退出 SistemBaslat - 无法保证两个线程中的哪一个将首先运行 KonsolaYaz 方法。
  • @ErimVarış:不,它也可用于本地运行的程序。
【解决方案2】:

如果您希望保持消息的顺序,您将必须只使用一个线程读取单个队列,并让所有其他线程将数据推送到其中。好消息是你的代码会简单得多。坏消息是,无论您想记录什么,您都必须有权访问队列(您可以创建一个静态记录器来缓解这种情况)。

编辑:建议您查看以下链接:Simple MultiThread Safe Log Class,而不是给您代码。 您应该找到所有答案。

【讨论】:

  • 你能给我写一个简单的解决方案吗?我也可以重写整个代码,这不是我一开始的问题。我只想为我的程序创建 4 个线程
  • 保持消息的顺序 - 写入是在从线程调用的 KonsolaYaz 方法中完成的。仅仅因为要写入的字符串是在构造函数中设置的,并且线程以特定的顺序启动 - 这并不能保证写入的顺序。为了使您的解决方案正常工作,必须将消息添加到构造函数中的队列中,而不是 KonsolaYaz 事件中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多