C#后台工作人员问题

C#后台工作人员问题,c#,backgroundworker,C#,Backgroundworker,我与c#的backgroundworker有问题。 我正在编写一个dll文件 这是我在VS 2019中类库(.NET Framework)类型项目中的代码: using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; us

我与c#的backgroundworker有问题。 我正在编写一个dll文件

这是我在VS 2019中类库(.NET Framework)类型项目中的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace States
{    
    public class ST
    {        
        public static void Read()
        {
            BackgroundWorker bgwMessage = new BackgroundWorker();
            bgwMessage.DoWork += new DoWorkEventHandler(BgwFileOpen_DoWork);
            bgwMessage.RunWorkerAsync();
        }
       
        private static void BgwFileOpen_DoWork(object sender, DoWorkEventArgs e)
        {
            MessageBox.Show("Ran");
        }
    }
}

当我使用Immediate窗口调用
Read()
方法时,后台工作人员的
DoWork
方法中的命令不会运行。逐行解阻塞问题表明
Read()
方法正在运行,但它不会以某种方式调用RunworkerAsync

*更新1: 启动线程也不起作用:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TradeStates
{
    
    public class ST
    {
        
        public static void Read()
        {
            Thread thr = new Thread(new ThreadStart(MSGshow));
            thr.Start();
        }
        public static void MSGshow()
        {
            MessageBox.Show("Ran");
        }


    }
}

有几件事

正确实现后台工作程序
DoWork
事件被触发一次以执行后台工作,并且不得执行任何访问UI控件/UI线程的操作

您还可以使用另外两个事件<代码>进度更改用于报告进度。例如,您可以实现该方法来更新进度条。另一个,我认为您应该感兴趣的是
RunWorkerCompleted
。在你的情况下,你会有

bgwMessage.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(BgwFileOpen_ShowDialog);
...
private void BgwFileOpen_ShowDialog(object sender, RunWorkerCompletedEventArgs e)
{
    MessageBox.Show("Ran");
}
其他一些想法

  • 您的后台工作程序通常应该是
    窗体
    或其他winforms类的属性,因为
    BackgroundWorker
    继承自
    组件
  • 当后台工作程序的父级被释放时,它应该调用后台工作程序上的
    Dispose()
该文档提供了一个关于如何正确使用该类的很好的示例

改为使用线程或任务 如果必须从
Read()
创建并启动worker,我建议您改为启动
线程,并让它在完成后向UI线程发送消息。然后,您的消息处理程序将启动消息框

您甚至可以使用
任务
,然后调用
MessageBox.Show()
,将继续添加到UI线程上的任务中

即时窗口问题 immediate窗口在执行线程或至少显示除其运行线程以外的其他线程的输出/结果时可能出现问题。它是为与您(开发人员)交互而设计的,而不是作为运行应用程序(如winforms)的全功能环境

我相信,如果您将
Read()
方法设计为接受正确实现的后台工作程序(即在
Read()
外部创建和设置),然后在
Read()
内部调用
RunWorkerAsync()
,消息框应该如预期的那样弹出——只是当您通过即时窗口时不会看到它。

一些事情

正确实现后台工作程序
DoWork
事件被触发一次以执行后台工作,并且不得执行任何访问UI控件/UI线程的操作

您还可以使用另外两个事件<代码>进度更改
用于报告进度。例如,您可以实现该方法来更新进度条。另一个,我认为您应该感兴趣的是
RunWorkerCompleted
。在你的情况下,你会有

bgwMessage.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(BgwFileOpen_ShowDialog);
...
private void BgwFileOpen_ShowDialog(object sender, RunWorkerCompletedEventArgs e)
{
    MessageBox.Show("Ran");
}
其他一些想法

  • 您的后台工作程序通常应该是
    窗体
    或其他winforms类的属性,因为
    BackgroundWorker
    继承自
    组件
  • 当后台工作程序的父级被释放时,它应该调用后台工作程序上的
    Dispose()
该文档提供了一个关于如何正确使用该类的很好的示例

改为使用线程或任务 如果必须从
Read()
创建并启动worker,我建议您改为启动
线程,并让它在完成后向UI线程发送消息。然后,您的消息处理程序将启动消息框

您甚至可以使用
任务
,然后调用
MessageBox.Show()
,将继续添加到UI线程上的任务中

即时窗口问题 immediate窗口在执行线程或至少显示除其运行线程以外的其他线程的输出/结果时可能出现问题。它是为与您(开发人员)交互而设计的,而不是作为运行应用程序(如winforms)的全功能环境


我相信,如果您将
Read()
方法设计为接受正确实现的后台工作程序(即在
Read()
外部创建和设置),然后在
Read()
内部调用
RunWorkerAsync()
,消息框应该如预期的那样弹出——只是当您通过即时窗口时不会看到它。

我建议使用任务。它适用于4.5以上的任何dotnet(4.0也适用于其他软件包)

然后,例如,在您的按钮单击事件上,只需调用:

private async void Button_Click(object sender, EventArgs e)
{
   await ST.Read();
   MessageBox.Show("Ran");
}
这不会在您执行大阅读任务时冻结您的视图,并在完成后返回按钮单击功能的下一行以显示对话框结果。

您甚至可以在Read调用之前添加一些代码来警告用户后台正在发生某些事情:)

我建议使用Tasks。它适用于4.5以上的任何dotnet(4.0也适用于其他软件包)

然后,例如,在您的按钮单击事件上,只需调用:

private async void Button_Click(object sender, EventArgs e)
{
   await ST.Read();
   MessageBox.Show("Ran");
}
这不会在您执行大阅读任务时冻结您的视图,并在完成后返回按钮单击功能的下一行以显示对话框结果。

在读取调用之前,甚至可以添加一些代码来警告用户在后台发生了什么事情:)

由于后台工作人员类是IDISPISPLE的,请考虑将其声明移动到字段中,然后在工作结束后再处理该字段。即时窗口是否始终能够显示消息框?假设您正在立即窗口w中执行命令