程序在此控制台中写入时在控制台中写入

时间:2014-01-08 17:43:51

标签: c# multithreading file-io console

当程序在此控制台中写入内容时,是否可以在控制台中编写内容?当您执行重复操作时重命名或删除某些文件,并且程序在控制台中编写了大量内容时,它会很有用。然后,当程序继续在控制台中写入时,您将能够编写一个命令来停止执行重复操作。我认为它不是很清楚,我用最合适的代码向我说明了这个事实(但我确切地认为它不起作用;))。我们有3个班级。

主要班级:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        private static bool m_Write;

        public static bool write
        {
            get { return m_Write; }
            set { m_Write = value; }
        }

        static void Main(string[] args)
        {
            int index = 0;

            Console.ReadLine();

            m_Write = true;

            Reader reader = new Reader();

            while (m_Write)
            {
                index++;

                Writer writer = new Writer(index.ToString());
            }

        }
    }
}

阅读课:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace ConsoleApplication1
{
    class Reader
    {
        private Thread m_Reading_Thread;
        private string m_text_To_Read;

        public Reader()
        {
            m_Reading_Thread = new Thread(new ThreadStart(Read));
            m_Reading_Thread.Start();
        }

        public void Read()
        {
            m_text_To_Read = Console.ReadLine();

            if (m_text_To_Read == "Stop")
            {
                Program.write = false;
            }
        }
    }
}

写作课:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace ConsoleApplication1
{
    class Writer
    {
        private Thread m_Writing_Thread;
        private string m_Text_To_Write;

        public Writer(string text_To_Write)
        {
            m_Text_To_Write = text_To_Write;

            m_Writing_Thread = new Thread(new ThreadStart(Write));
            m_Writing_Thread.Start();
        }

        public void Write()
        {
            Console.WriteLine(m_Text_To_Write);
        }
    }
}

3 个答案:

答案 0 :(得分:2)

这并不像你想要的那样复杂。一般来说,有两种方法可以做到这一点。您可以启动后台线程来执行写操作,并让控制台上的主线程块等待读取,或者您可以让主线程写入并让后台线程执行读取操作。我最喜欢第一个解决方案:

public class Program
{
    private static readonly ManualResetEvent StopWriting = new ManualResetEvent(false);

    private static void Main(string[] args)
    {
        Thread t = new Thread(WriterFunc);
        t.Start();

        string input;
        do
        {
            input = Console.ReadLine();
        } while (input != "stop");

        // Tell the thread to stop writing
        StopWriting.Set();

        // And wait for the thread to exit
        t.Join();
    }

    private static void WriterFunc()
    {
        int index = 0;
        while (!StopWriting.WaitOne(Timeout.Infinite))
        {
            ++index;
            Console.WriteLine(index.ToString());
        }
    }
}

请注意,我在这里使用ManualResetEvent而不是Boolean标志。更好的解决方案是使用CancellationToken。使用标志可能会导致各种有趣的问题,因为编译器可能会确定变量无法更改(它假定是单线程访问)。即使在更改变量后,您的线程也可能继续运行。

如果您希望主线程执行写操作,并且后台线程执行读取:

public class Program
{
    private static readonly ManualResetEvent StopWriting = new ManualResetEvent(false);

    private static void Main(string[] args)
    {
        Thread t = new Thread(ReaderFunc);
        t.Start();

        int index = 0;
        while (!StopWriting.WaitOne(Timeout.Infinite))
        {
            ++index;
            Console.WriteLine(index.ToString());
        }

        // Wait for the background thread to exit
        t.Join();
    }

    private static void ReaderFunc()
    {
        string input;
        do
        {
            input = Console.ReadLine();
        } while (input != "stop");

        // Tell the main thread to stop writing
        StopWriting.Set();
    }
}

答案 1 :(得分:1)

这样的事情会起作用:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var w = new Writer();
            var r = new Reader();

            while (!r.finish)
            {
                w.enabled = true;
                string k = Console.ReadKey(false).KeyChar.ToString();
                w.enabled = false;

                string line = k + Console.ReadLine();
                r.Read(line);
            }
        }
    }

    class Writer
    {
        public bool enabled = true;

        public Writer()
        {
            var timer = new System.Timers.Timer(1000);
            timer.Elapsed += (a, b) =>
            {
                if(enabled)
                    Console.WriteLine("Test");
            };
            timer.Start();
        }
    }

    class Reader
    {
        public bool finish = false;

        public void Read(string line)
        {
            if (line == "stop")
            {
                finish = true;
            }
        }
    }
}

如果Writer在上面写下你输入的内容,请不要担心,Console.ReadLine()只考虑你输入的内容。

答案 2 :(得分:0)

对于控制台应用程序,没有两个线程可以在同一时间将数据写入屏幕。

AFAIK,在上面的回答中,Writes()的构造函数会一直执行,直到它完成运行。然后控件将传递给Reader()。所以我认为这不适用于你需要的东西。如果我错了,请纠正我。