Winforms和后台工作器

本文关键字:工作 后台 Winforms | 更新日期: 2023-09-27 18:09:38

我现在有一个控制台应用程序,它监视文件夹中的文件,然后根据规则和文件名,将任何新文件复制到网络上的一个位置。

我有一个要求,使应用程序更漂亮,所以决定用一个简单的WinForms单表单应用程序,显示状态和"最近更新的文件"类型的信息。

控制台应用程序是以这样一种方式编写的,即所有控制台显示信息都通过一个方法,我称之为"Notify",带有两个参数。一个字符串,用来显示我想让用户看到的信息,还有一个ErrorLevel Enum,如果'Normal'显示为绿色文本,如果Warning显示为黄色,如果error显示为红色。但关键是,我所有的代码只是使用'Notify'方法来输出任何文本。

我想把我的控制台应用程序变成一个正常的类,作为WinForms项目的后台工作器运行它,并在线程中的Notify方法安全地将更新发送到WinForms应用程序。我认为这可以用事件来完成,但我不确定什么是最好的处理方式。你能提出一个使它工作的方法吗?

有"调用"的方式做事情。好吗?比如:

this.BeginInvoke (new MethodInvoker(() => UpdateLabel(s));

这似乎是基本的,但我想仍然使用我的Notify方法,并有发送消息到UI层。

我还需要控制台应用程序向线程发送消息。例如,'Stop',然后我运行代码,优雅地退出线程…还有'Refresh',它在线程内执行一些逻辑操作。

另一个选项是将处理类作为服务运行?然后有一个UI连接到系统服务并获取更新?我从来没有做过这样的事情,但是这个过程应该一直运行……

此刻,我有我的代码运行,但没有更新到UI:

public partial class MainForm : Form
{
    BackgroundWorker _bw = new BackgroundWorker();
    public MainForm()
    {
        InitializeComponent();
    }
    private void MainForm_Load(object sender, EventArgs e)
    {
        _bw.DoWork += bw_DoWork;
        _bw.RunWorkerAsync();
    }
    private void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        var bw = sender as BackgroundWorker;
        var monitor = new Monitor();
        monitor.RunMe();
    }
}

我想我只需要找到一种方法来获得我的Notify方法在我的线程发送消息或一些东西(一个对象,我创建,与消息字符串和ErrorCode属性?)回到我的UI,并在UI上安全地处理它。

下面是类(线程)中的代码…

public class Monitor
    {
        public void RunMe()
        {
            Notify("Checking for network connectivity...", Constants.ErrorLevel.Information);
            if (FileManagement.FolderExists(Constants.FolderToMonitor) == false)
            {
                Notify("Unable to monitor folder - Aborting.", Constants.ErrorLevel.Error);
                Console.ReadKey();
                return;
            }
            Notify("OK", Constants.ErrorLevel.Information);
....
}

Winforms和后台工作器

可能有更好的方法,但是如果您的Notify方法需要与GUI交互,请尝试使用BackgroundWorker上的ReportProgress事件。您可以传递一个对象作为状态参数,并且可能只是忽略进度值。