使用背景工人多类在C# [英] Using background worker with multiple classes in C#

查看:66
本文介绍了使用背景工人多类在C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我学习C#编程,并有大部分的基础已经下降。我在使用的后台工作,并使用它与多个类的麻烦。这是我写,我有以下类的备份程序。



lacie.cs --->用于搜索备份设备
main.cs --->主入口
size.cs --->确定备份
xml.cs的大小--->读取目录的XML配置文件进行备份。



我会告诉我有什么在main.cs至今。



[main.cs代码]

 使用系统; 
使用System.Collections.Generic;
使用System.Linq的;
使用System.Text;

命名空间QXBackup
{
类主要
{
静态无效的主要(字串[] args)
{
的LaCie BackupDrive =新的LaCie();
BackupDrive.findLacie();

XML XMLFILE =新的XML();
xmlFile.ProcessXML();

大小BackupSize =新的大小();
BackupSize.GetSize(xmlFile.Path);

INT SizeofBackup =(INT)(((BackupSize.BackupSize)/ 1024f)/ 1024f)/ 1024;
Console.WriteLine(驱动器号:+ BackupDrive.Drive);
Console.WriteLine(卷名称:+ BackupDrive.VolumeLabel);
Console.WriteLine(自由空间+ Convert.ToString(BackupDrive.AvailableSize)+G);
Console.WriteLine(莱希的尺寸:+ Convert.ToString(BackupDrive.TotalSize)+G);
Console.WriteLine(备份大小:+ Convert.ToString(SizeofBackup +G));
Console.WriteLine(备份+ BackupSize.FolderCount + + + BackupSize.FileCount找到的文件,文件夹。);
Console.ReadKey(真);
}
}
}

[结束main.cs代码

]

现在该程序工作正常,到目前为止并显示我已要求它打印在屏幕上。我的问题如下。当它熄灭计算备份作业的大小程序只是坐在那里等着德size.cs类返回值。我希望能够使用的背景工人为具有程序加载和更新的大小数,因为它是计算的大小和显示在屏幕上。这是一个控制台程序,我不知道如果我将能够做到这一点,但它也将帮助我,我计划在将来变成一个基于GUI的程序。可有一个人帮我这个我一直在尝试各种事情,并没有什么作品。我想我的混淆是引进后台工作,以及如何正确地执行它。感谢您的帮助。


解决方案

也许这个代码中,我作为一个例子之前,对您会有帮助。这是只使用基本的线程,但它类似于一个BackgroundWorker是如何工作的,它使用的事件信号完成和更新。如果你看看哪里有注释信号完成通过激发事件这是触发一个事件来指示完成任务,返回一些信息。你也可以同样创建其他类型的如ProgressUpdate事件事件,并从CalculateSize线程多次启动它,这样就可以逐步更新进度。现在,我实际上有下面分成多个等级,而不是全部一起捣碎,但你的想法。你必须在一个类中有关处理事件的东西,这很可能是你的表格订户,然后线程和处理将是你的类,它的尺寸计算。

 使用系统; 
使用System.Collections.Generic;
使用System.ComponentModel;
使用System.Data这;
使用System.Drawing中;
使用System.Text;使用System.Windows.Forms的
;
使用的System.Threading;

命名空间ThreadWithDataReturnExample
{
公共部分Form1类:表格
{
私人线程线程1 = NULL;

公共Form1中()
{
的InitializeComponent();

线程1 =新主题(新的ThreadStart(this.threadEntryPoint));
Thread1Completed + =新AsyncCompletedEventHandler(thread1_Thread1Completed);
}

私人无效startButton_Click(对象发件人,EventArgs五)
{
thread1.Start();
//或者,您也可以在这种传递一些对象
//作为开始(someObject);
//随着apprioriate锁定,或协议,其中
//没有其他线程访问对象,直到
//事件信号线程完成时,
//其他类与到对象
A参考//将能够访问这些数据。
//但是相反,我将使用AsyncCompletedEventArgs
//在发出完成信号
}

无效事件thread1_Thread1Completed(对象发件人,AsyncCompletedEventArgs E)
{
如果(this.InvokeRequired)
{//当元帅的电话,如果我们不在GUI线程
的BeginInvoke(新AsyncCompletedEventHandler(thread1_Thread1Completed),
新对象[] {发送,E});
}
,否则
{
//如果发生错误显示错误
//如果没有出错,处理数据
如果(e.Error == NULL)
{//那么成功

MessageBox.Show(工人线程成功完成);
DataYouWantToReturn someData = e.UserState为DataYouWantToReturn;
MessageBox.Show(您的数据大人:+ someData.someProperty);

}
,否则//错误
{
MessageBox.Show(出现以下错误:+ Environment.NewLine + e.Error.ToString()) ;
}
}
}

#地区我实际上把所有这一切到它自己的类
私人无效threadEntryPoint()
{
//做了一堆东西,

//当你完成:
//初始化要返回
DataYouWantToReturn dataYouWantToReturn =新DataYouWantToReturn数据对象();
dataYouWantToReturn.someProperty =更多的数据;通过激发事件
OnThread1Completed(新AsyncCompletedEventArgs(空,假,dataYouWantToReturn))

//信号完成;
}

///<总结>
///当处理完毕或发生错误时发生。
///< /总结>
公共事件AsyncCompletedEventHandler Thread1Completed;
受保护的虚拟无效OnThread1Completed(AsyncCompletedEventArgs E)
{
//本地复制
AsyncCompletedEventHandler处理器= Thread1Completed;
如果(处理!= NULL)
{
处理器(这一点,E);
}
}
#endregion

}
}


I am learning to program in C# and have most of the basics down already. I am having trouble using the background worker and using it with multiple classes. This is a backup program that I am writing I have the following classes.

lacie.cs ---> used to search for backup device main.cs ---> Main entry size.cs ---> Determines the size of the backup xml.cs ---> Reads an xml config file of directories to be backed up.

I will show what I have in the main.cs so far.

[main.cs code]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace QXBackup
{
    class main
    {
        static void Main(string[] args)
        {
            lacie BackupDrive = new lacie();
            BackupDrive.findLacie();

            xml xmlFile = new xml();
            xmlFile.ProcessXML();

            size BackupSize = new size();
            BackupSize.GetSize(xmlFile.Path);

            int SizeofBackup = (int)(((BackupSize.BackupSize) / 1024f) / 1024f) / 1024;
            Console.WriteLine("Drive Letter: " + BackupDrive.Drive);
            Console.WriteLine("Volume Name: " + BackupDrive.VolumeLabel);
            Console.WriteLine("Free Space: " + Convert.ToString(BackupDrive.AvailableSize) + "G");
            Console.WriteLine("Size of Lacie: " + Convert.ToString(BackupDrive.TotalSize) + "G");
            Console.WriteLine("Backup Size: " + Convert.ToString(SizeofBackup + "G"));
            Console.WriteLine("Backing up " + BackupSize.FileCount + " files found in " + BackupSize.FolderCount + " folders.");
            Console.ReadKey(true);
        }
    }
}

[end main.cs code]

now the program works fine so far and displays what I have asked it to print on the screen. My problem is as follows. When it goes off to calculate the size of the backup job the program just sits there waiting for teh size.cs class to return the value. I want to be able to use the background worker to have the program load and update the size number as it is calculating the size and show that on the screen. This is a console program and I am not sure if I will be able to do that but it will also help me as I plan to in the future turn this into a GUI based program. Can some one help me with this I have been trying all kinds of things and nothing works. I think my confusion is were to introduce the background worker and how to implement it correctly. Thanks for the help

解决方案

Maybe this code I've used as an example before will help you out. This is just using basic threading, but it's similar to how a BackgroundWorker works in that it uses events to signal completion and updates. If you look where there is the comment "signal completion by firing an event" this is firing an event to indicate the task is done and return some information. You could just as well create other types of events like a ProgressUpdate event and fire it repeatedly from a CalculateSize thread so that you can gradually update a ProgressBar. Now I would actually have the below split up into multiple classes and not all mashed together, but you get the idea. You'd have the stuff related to handling the event in one class, the subscriber which would probably be your Form, and then the threading and processing would be in your class that does the Size calculation.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace ThreadWithDataReturnExample
{
    public partial class Form1 : Form
    {
        private Thread thread1 = null;

        public Form1()
        {
            InitializeComponent();

            thread1 = new Thread(new ThreadStart(this.threadEntryPoint));
            Thread1Completed += new AsyncCompletedEventHandler(thread1_Thread1Completed);
        }

        private void startButton_Click(object sender, EventArgs e)
        {
            thread1.Start();
            //Alternatively, you could pass some object
            //in such as Start(someObject);
            //With apprioriate locking, or protocol where
            //no other threads access the object until
            //an event signals when the thread is complete,
            //any other class with a reference to the object 
            //would be able to access that data.
            //But instead, I'm going to use AsyncCompletedEventArgs 
            //in an event that signals completion
        }

        void thread1_Thread1Completed(object sender, AsyncCompletedEventArgs e)
        {
            if (this.InvokeRequired)
            {//marshal the call if we are not on the GUI thread                
                BeginInvoke(new AsyncCompletedEventHandler(thread1_Thread1Completed),
                  new object[] { sender, e });
            }
            else
            {
                //display error if error occurred
                //if no error occurred, process data
                if (e.Error == null)
                {//then success

                    MessageBox.Show("Worker thread completed successfully");
                    DataYouWantToReturn someData = e.UserState as DataYouWantToReturn;
                    MessageBox.Show("Your data my lord: " + someData.someProperty);

                }
                else//error
                {
                    MessageBox.Show("The following error occurred:" + Environment.NewLine + e.Error.ToString());
                }
            }
        }

        #region I would actually move all of this into it's own class
            private void threadEntryPoint()
            {
                //do a bunch of stuff

                //when you are done:
                //initialize object with data that you want to return
                DataYouWantToReturn dataYouWantToReturn = new DataYouWantToReturn();
                dataYouWantToReturn.someProperty = "more data";

                //signal completion by firing an event
                OnThread1Completed(new AsyncCompletedEventArgs(null, false, dataYouWantToReturn));
            }

            /// <summary>
            /// Occurs when processing has finished or an error occurred.
            /// </summary>
            public event AsyncCompletedEventHandler Thread1Completed;
            protected virtual void OnThread1Completed(AsyncCompletedEventArgs e)
            {
                //copy locally
                AsyncCompletedEventHandler handler = Thread1Completed;
                if (handler != null)
                {
                    handler(this, e);
                }
            }
        #endregion

    }
}

这篇关于使用背景工人多类在C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆