[英]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 可能在执行线程时遇到问题,或者至少显示除了它正在运行的线程之外的其他线程的输出/结果。 它旨在与您(开发人员)进行交互,而不是作为运行应用程序的全功能环境,例如 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.