C# 将实时日志窗口设置为从不同线程写入的最佳体系结构,如visualstudio中的输出窗口

C# 将实时日志窗口设置为从不同线程写入的最佳体系结构,如visualstudio中的输出窗口,c#,.net,multithreading,architecture,C#,.net,Multithreading,Architecture,我正在设计一个应用程序,它在不同的线程上运行不同的组件。我需要一种方法向用户界面报告这些组件的状态和它们完成的任务,以及是否发生任何错误。我的第一种方法是将所有不同组件写入日志文件。然后我监视该文件的更改,以便在文本框(我的输出窗口)中重新加载更改。然而,我注意到使用文件监视器的性能不是很好,它会减慢组件线程及其任务的速度。所以我想在vs2010中创建一些类似输出窗口的东西,在那里他们可以在调试时记录任何数据,它看起来非常高效,可以保存大量数据。你知道什么是最好的方法吗?一个重要的事实是,应该有

我正在设计一个应用程序,它在不同的线程上运行不同的组件。我需要一种方法向用户界面报告这些组件的状态和它们完成的任务,以及是否发生任何错误。我的第一种方法是将所有不同组件写入日志文件。然后我监视该文件的更改,以便在文本框(我的输出窗口)中重新加载更改。然而,我注意到使用文件监视器的性能不是很好,它会减慢组件线程及其任务的速度。所以我想在vs2010中创建一些类似输出窗口的东西,在那里他们可以在调试时记录任何数据,它看起来非常高效,可以保存大量数据。你知道什么是最好的方法吗?一个重要的事实是,应该有一种方法可以将所有组件线程与日志输出窗口进行通信,以显示结果、避免冲突等。我使用的是.NET 4.0,我认为您可以通过写入日志文件来改进您的想法,只需异步执行,这样就不会阻塞线程


您可以使用或之类的东西。

我不明白为什么您不能在这个示例代码中使用这样的东西(我必须说,我认为你正在做所有的同步和线程停止,这只是使用控件的一个快速例子。调用使线程安全,也可以使用RealNojk,它不会阻止正在写入文本框的线程):

List threads=newlist();
布尔封闭螺纹;
私有无效按钮1\u单击(对象发送者,事件参数e)
{
closeThreads=false;
对于(int i=1;i<10;i++)
{
线程t=新线程(新参数化的ThreadStart(ThreadMethod));
添加(t);
t、 启动(i);
}
}
私有无效按钮2\u单击(对象发送者,事件参数e)
{
closeThreads=true;
foreach(螺纹中的螺纹t)
{
if(t.ThreadState!=ThreadState.Stopped)
t、 加入(3);
}
}
委托无效textWriter(字符串textToWrite);
void WriteText(字符串textToWrite)
{
this.textBox1.AppendText(textToWrite);
}
无效线程方法(对象i)
{
int threadNumber=(int)i;
int currentNumber=100*threadNumber;
Random rand=新随机数(螺纹编号);
而(!closeThreads)
{
currentNumber=(currentNumber+rand.Next(0100))%1000;
线程睡眠(currentNumber);
//textBox1.Invoke(新textWriter(WriteText),新对象[]{“Thread”+threadNumber.ToString()+“”+currentNumber.ToString()+Environment.NewLine});
//这不会阻塞你的线程
string text=“Thread”+threadNumber.ToString()+“”+currentNumber.ToString()+Environment.NewLine;
textBox1.BeginInvoke(新的textWriter(WriteText),新对象[]{text});
}
}

为了尝试代码,您需要制作一个包含两个
按钮和一个
文本框的表单。我已经编辑了您的标题。请参见“”,其中一致意见是“不,他们不应该”。这个问题主要是基于观点的。你以前试过吗?你认为这是最好的方法吗?为什么它需要被带到一个文件中,而不是仅仅进入文本框/数据网格?我忘了提到一些与HD一起工作的组件,所以不确定监控日志记录是否会以某种方式减慢速度。我想的另一件事是所有内容都记录到日志中,但只加载N行。因此,它加载速度更快,磁盘活动不多,用户可以保留所有日志,但只需实时查看最新的日志。1.是的,我尝试过异步日志记录,它不会影响性能。2.文件(或其他持久位置)如果你需要保留记录的数据,这很好。Nlog和log4net支持不同的附加器,因此你可以使用文件或db等。似乎你想实现Unix命令尾部的功能,用于读取。如果你要尝试log4net,此应用可能会很有用。看起来不错,我将尝试改进当前的算法,看看我是否让它变得更高效,更好的用户体验。
        List<Thread> threads = new List<Thread>();
        bool closeThreads;
        private void button1_Click(object sender, EventArgs e)
        {
            closeThreads = false;
            for (int i = 1; i < 10; i++)
            {
                Thread t = new Thread(new ParameterizedThreadStart(ThreadMethod));
                threads.Add(t);
                t.Start(i);
            }
        }
        private void button2_Click(object sender, EventArgs e)
        {
            closeThreads = true;
            foreach (Thread t in threads)
            {
                if (t.ThreadState != ThreadState.Stopped)
                    t.Join(3);
            }
        }

        delegate void textWriter(string textToWrite);
        void WriteText(string textToWrite)
        {
            this.textBox1.AppendText(textToWrite);
        }

        void ThreadMethod(object i)
        {
            int threadNumber = (int)i;
            int currentNumber = 100 * threadNumber;
            Random rand = new Random(threadNumber);
            while(!closeThreads)
            {
                currentNumber = (currentNumber + rand.Next(0,100))%1000;
                Thread.Sleep(currentNumber);
                //textBox1.Invoke(new textWriter(WriteText), new object[]{"Thread " + threadNumber.ToString() + " " + currentNumber.ToString() + Environment.NewLine});
                //this won't block your threads
                string text = "Thread " + threadNumber.ToString() + " " + currentNumber.ToString() + Environment.NewLine;
            textBox1.BeginInvoke(new textWriter(WriteText), new object[]{text});
            }
        }