C#Windows窗体-将信息输出到文本框而不会崩溃

本文关键字:崩溃 文本 窗体 信息 输出 C#Windows | 更新日期: 2023-09-27 18:00:04

在Windows窗体应用程序中,我使用Quartz.NET每隔几分钟运行一些任务。以前,这个应用程序是一个基于时间表调用的控制台应用程序,但由于各种原因,这并不理想——当时所有调试信息都输出到控制台。

在这个版本中,我需要一种在用户屏幕上显示作业的调试信息的方法。我最初的想法是在运行作业时显示一个新表单,所有调试信息都会附加到该表单上的多行文本框中。然而,这不起作用,因为当我这样做时,大多数应用程序似乎都会崩溃。

还有其他想法吗?

编辑:很抱歉造成任何混淆。这就是作业执行时的名称:

    public virtual void Execute(JobExecutionContext context)
    {
        RunJob jobForm = new RunJob();
        jobForm.Show();
        jobForm.JobLabel = context.JobDetail.JobDataMap.GetString("Name");
        for (int i = 0; i < 100; i++)
        {
            jobForm.WriteLine(i.ToString());
        }
        jobForm.Hide();
    }

这是"RunJob"表单的内容:

public partial class RunJob : Form
    {
        public string JobLabel
        {
            get
            {
                return lblJobName.Text;
            }
            set
            {
                lblJobName.Text = value;
            }
        }
        public void WriteLine(string text)
        {
            textBox1.AppendText(text + Environment.NewLine);
        }
        public RunJob()
        {
            InitializeComponent();
        }
    }

基本上,当文本被附加时,RunJob窗口会冻结,而理想情况下它只是平滑地添加文本。我知道"崩溃"这个词选得很差!我的借口是现在是凌晨,嗯哼

C#Windows窗体-将信息输出到文本框而不会崩溃

我在上面的代码中没有看到任何可能导致死锁的错误,除了这一行:jobForm.JobLabel = context.JobDetail.JobDataMap.GetString("Name");

这条线是干什么的,这条线一定有问题,试着放一些硬编码的字符串,而不是context.JobDetail.JobDataMap.GetString("Name");,然后告诉我它是否仍然不起作用。

作业和UI表单显然应该在单独的线程中。作业线程应该写入表单,然后在不需要时关闭它。

假设您有一个在UI线程上调用的Action操作:

public virtual void Execute(JobExecutionContext context)
{
    RunJob jobForm;
    var name = context.JobDetail.JobDataMap.GetString("Name");
    action(()=> { jobForm = new RunJob(); jobForm.Show(); jobForm.JobLabel = name;});
    for (int i = 0; i < 100; i++)
    {
        var txt = i.ToString();
        action(()=>{ jobForm.WriteLine(txt); });
    }
    action(()=> { jobForm.Hide(); });
}