C# 多线程用户界面状态记录

C# 多线程用户界面状态记录,c#,multithreading,winforms,C#,Multithreading,Winforms,我有一个多线程windows窗体应用程序,我想在其中添加UI日志选项,以在文本框或其他UI控件中显示线程活动 目前,我能够使用主窗体中的委托在文本框中显示所有线程的日志 我正在寻找一种方法,一次只显示一个线程的日志(这取决于用户选择对应于该线程的datagridview行),并且随着线程仍然在后台运行,并且更新了新的日志而不断更新 理想情况下,我希望使用单个文本框根据用户选择更改其内容 比方说,当用户单击网格的第3行时,文本框将清除任何以前的内容,并使用线程t3的日志进行更改,并继续实时更新 请

我有一个多线程windows窗体应用程序,我想在其中添加UI日志选项,以在文本框或其他UI控件中显示线程活动

目前,我能够使用主窗体中的委托在文本框中显示所有线程的日志

我正在寻找一种方法,一次只显示一个线程的日志(这取决于用户选择对应于该线程的datagridview行),并且随着线程仍然在后台运行,并且更新了新的日志而不断更新

理想情况下,我希望使用单个文本框根据用户选择更改其内容

比方说,当用户单击网格的第3行时,文本框将清除任何以前的内容,并使用线程t3的日志进行更改,并继续实时更新

请建议我做它的方法,即使它使用不同的控制以外的文本框。非常感谢您的帮助

PS:只是想说明一下,文本框不是DataGridView的一部分。它应该是DGV外部的状态记录器。

而不是

writeToLog = delegate(string s)
{
    if (textBox1.InvokeRequired)
    {
        var text = new Addlog(this.LoadLogTextBoxCallBack);
        this.Invoke(text, new object[] { s });
    }
    else
        this.textBox1.Text = string.Format("{0}{1} {2}{3}",Environment.NewLine, DateTime.Now, s, this.textBox1.Text);
}
您需要两种方法:

Dictionary<string, string> _log = new Dictionary<string, string>();

void UpdateTextBox(string id)
{
    if (textBox1.InvokeRequired)
        Invoke(UpdateTextBox, new object[] { id });
    else
        textBox1.Text = _log[id];
}

void AddToLog(string id, string message)
{
    // add new or update
    if(_log.ContainsKey(id))
        _log[id] = string.Format("{0}{1} {2}{3}", Environment.NewLine, DateTime.Now, message, _log[id]);
    else
        _log.Add(id, string.Format("{0}{1} {2}", Environment.NewLine, DateTime.Now, message);
    UpdateTextBox(id);
}
Dictionary\u log=newdictionary();
无效UpdateTextBox(字符串id)
{
if(textBox1.invokererequired)
调用(UpdateTextBox,新对象[]{id});
其他的
textBox1.Text=_log[id];
}
void AddToLog(字符串id、字符串消息)
{
//添加新的或更新的
如果(_log.ContainsKey(id))
_log[id]=string.Format(“{0}{1}{2}{3}”,Environment.NewLine,DateTime.Now,message,_log[id]);
其他的
_添加(id,string.Format(“{0}{1}{2}”、Environment.NewLine、DateTime.Now、message);
UpdateTextBox(id);
}
从线程调用
AddToLog()
,从DGV selected changed事件调用
UpdateTextBox


有很多改进(线程安全?字典初始化,存储id)。我把它们留给你。如果是我,那么将有一个
Log
类和
Add()
方法和添加的
事件,应该使其更具面向对象性。

首先,询问用户线程是什么。除非他能回答您线程是什么……否则您正在做一些非常非常非常错误的事情。用户只关心“工作单位”或“进程”。此外,每个工作单元都不应该需要一个线程。事实上,不应该需要多个线程(最有可能)。和@Aron一样,我不明白为什么它是多线程的。必须向用户介绍应用程序中的作业概念(如果有多个作业同时运行,并且您希望仅显示一个作业的进度,由用户选择)。您的代理将需要某种标识(作业id),然后存储最后一个(或全部)如果用户选择使用此id显示作业,则在某些列表中显示来自该id的消息,并切换到此列表显示。听起来/看起来不是很难,或者需要架构。那么问题出在哪里?不确定您的意思。在这种情况下,用户会看到datagridview,其中每行通过线程异步执行某些任务。t1对应于DGV的第1行。当用户单击特定行时,文本框中应仅显示该特定线程的日志。同样,当选择其他行时,文本框应清除数据并显示与新行相对应的数据。主要问题是使用消息实时更新文本框,直到线程本身退出。hope很清楚。为什么不改用listview呢?一个要求显示项目的虚拟化视图会起作用。@Sinatr编辑OP以声明文本框在DGV之外。