繁体   English   中英

C# 后台工作人员问题

[英]C# backgroundworker issue

我在 c# 中遇到了后台工作人员的问题。 我正在编写 dll 文件。

这是我在 VS 2019 中的 Class 库(.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");
        }
    }
}

当我使用即时window 调用Read()方法时,后台工作人员的DoWork方法中的命令不会运行。 逐行调试问题表明Read()方法正在运行,但它没有以某种方式调用 RunworkerAsync。

*Update1:启动线程也不起作用:

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 线程的操作。

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

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

其他一些想法

  • 您的后台工作人员通常应该是Form或其他 winforms class 的属性,因为BackgroundWorker继承自Component
  • 当后台工作人员的父级被释放时,它应该在后台工作人员上调用Dispose()

BackgroundWorker Class文档提供了一个很好的示例,说明如何正确使用 class。

改用线程或任务

如果您必须从Read()创建和启动工作线程,我建议您改为启动一个Thread ,并在完成后让它向 UI 线程发送一条消息。 然后,您的消息处理程序将启动消息框。

您甚至可以使用Task ,然后向 UI 线程上继续的任务添加一个延续,调用MessageBox.Show()

即时 Window 问题

似乎即时 window 可能在执行线程时遇到问题,或者至少显示除了它正在运行的线程之外的其他线程的输出/结果。 它旨在与您(开发人员)进行交互,而不是作为运行应用程序的全功能环境,例如 winforms。

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

我建议使用任务。 它适用于 4.5 以上的任何 dotnet(4.0 还带有附加包)

using System.Threading.Tasks;
public class ST
{        
    public static async Task Read()
    {
        await Task.Run(() => {
              //Do some big work here
        };
    }               
}

然后例如在您的按钮单击事件中调用:

private async void Button_Click(object sender, EventArgs e)
{
   await ST.Read();
   MessageBox.Show("Ran");
}

这不会在您执行大型读取任务时冻结您的视图,并且在完成显示对话框结果后将返回到 Button_Click function 的下一行。
您甚至可以在 Read 调用之前添加一些代码,以警告用户后台正在发生某些事情:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM