Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中对多个类使用后台工作程序#_C#_Visual Studio 2008_C# 3.0 - Fatal编程技术网

C# 在C中对多个类使用后台工作程序#

C# 在C中对多个类使用后台工作程序#,c#,visual-studio-2008,c#-3.0,C#,Visual Studio 2008,C# 3.0,我正在学习用C语言编程,并且已经掌握了大部分的基础知识。我在使用后台工作程序和将其用于多个类时遇到问题。这是我正在编写的一个备份程序,我有以下几个类 lacie.cs-->用于搜索备份设备 main.cs-->main条目 size.cs-->确定备份的大小 xml.cs-->读取要备份的目录的xml配置文件 我将展示到目前为止我在main.cs中拥有的内容 [main.cs代码] using System; using System.Collections.Generic; using Sys

我正在学习用C语言编程,并且已经掌握了大部分的基础知识。我在使用后台工作程序和将其用于多个类时遇到问题。这是我正在编写的一个备份程序,我有以下几个类

lacie.cs-->用于搜索备份设备 main.cs-->main条目 size.cs-->确定备份的大小 xml.cs-->读取要备份的目录的xml配置文件

我将展示到目前为止我在main.cs中拥有的内容

[main.cs代码]

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);
        }
    }
}
[结束main.cs代码]

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);
        }
    }
}

到目前为止,该程序运行良好,并在屏幕上显示我要求它打印的内容。我的问题如下。当它开始计算备份作业的大小时,程序只是坐在那里等待size.cs类返回值。我希望能够使用后台工作程序加载程序,并在计算尺寸时更新尺寸编号,并在屏幕上显示。这是一个控制台程序,我不确定我是否能够做到这一点,但它也将帮助我,因为我计划在未来将其变成一个基于GUI的程序。有人能帮我吗?我一直在尝试各种各样的事情,但都不管用。我想我的困惑是如何介绍后台工作人员以及如何正确实施它。感谢您的帮助

作为您的问题请求,这将向您展示如何使用后台工作程序组件。 不过,当您使用更复杂的线程时,最好编写类似aaronls提供的内容

Size类应该包含backgroundWorker线程,并且
BackupSize.GetSize(“PathHere”)
应该进行异步调用以启动后台工作线程

在DoWork方法中,您可以通过调用
backgroundWorker.ReportProgress(i)来报告工作进度

在ReportProgress委托内部,您可以创建一个事件通知,该通知可以由主gui连接到

class main
{
    static void Main(string[] args)
    {

        size BackupSize = new size();
        BackupSize.GetSize("path");
        BackupSize.ProgressEvent += new ProgressEventHandler(BackupSize_ProgressEvent);

        // BackupSize.BackupSize will not be accurate until the thread is finished.
        // You may want to take that into consideration
        int SizeofBackup = (int)(((BackupSize.BackupSize) / 1024f) / 1024f) / 1024;

        Console.ReadLine();

    }

    static void BackupSize_ProgressEvent(object source, int progress)
    {
        Console.WriteLine(String.Format("Progress: {0}", progress));
    }
}

// This is the delegate that acts as the event handler for your progress events
public delegate void ProgressEventHandler(object source, int progress);

public class size
{
    private readonly BackgroundWorker backgroundWorker;
    public event ProgressEventHandler ProgressEvent;

    public size()
    {
        backgroundWorker = new BackgroundWorker { WorkerReportsProgress = true };
        backgroundWorker.DoWork += backgroundWorker_DoWork;
        backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged;
    }

    public void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        // do something with progress
        ProgressEvent.Invoke(sender, e.ProgressPercentage);
    }

    void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        String Path = e.Argument as String;

        // Do something with Path;

        // Simulate work
        for (int i = 1; i <= 100; i++)
        {
            // Get the size of the Here

            // Report the Progress
            backgroundWorker.ReportProgress(i);        
            Thread.Sleep(10);
        }
    }

    public void GetSize(String path)
    {
        backgroundWorker.RunWorkerAsync(path);
    }
}
主类
{
静态void Main(字符串[]参数)
{
大小备份大小=新大小();
BackupSize.GetSize(“路径”);
BackupSize.ProgressEvent+=新的ProgressEventHandler(BackupSize\u ProgressEvent);
//BackupSize。直到螺纹完成后,BackupSize才会准确。
//你可以考虑一下
int-SizeofBackup=(int)((BackupSize.BackupSize)/1024f)/1024;
Console.ReadLine();
}
静态void BackupSize\u ProgressEvent(对象源,int-progress)
{
WriteLine(String.Format(“Progress:{0}”,Progress));
}
}
//这是充当进度事件的事件处理程序的委托
公共委托void ProgressEventHandler(对象源,int progress);
公营班级人数
{
私有只读后台工作程序后台工作程序;
公共事件ProgressEventHandler ProgressEvent;
公共规模()
{
backgroundWorker=新的backgroundWorker{WorkerReportsProgress=true};
backgroundWorker.DoWork+=backgroundWorker\u DoWork;
backgroundWorker.ProgressChanged+=backgroundWorker\u ProgressChanged;
}
public void backgroundWorker_ProgressChanged(对象发送方,ProgressChangedEventArgs e)
{
//做一些有进步的事情
ProgressEvent.Invoke(发送方,例如ProgressPercentage);
}
无效backgroundWorker_DoWork(对象发送方,DoWorkEventArgs e)
{
字符串路径=e。参数为字符串;
//用路径做点什么;
//模拟工作

对于(int i=1;i也许我以前用作示例的这段代码可以帮助您解决问题。这只是使用基本线程,但与BackgroundWorker的工作方式类似,它使用事件来表示完成和更新。如果您查看注释“通过触发事件来表示完成”这是触发一个事件以指示任务已完成并返回一些信息。您也可以创建其他类型的事件,如ProgressUpdate事件,并从CalculateSize线程重复触发它,以便您可以逐步更新ProgressBar。现在,我会将下面的内容拆分为多个类,而不是全部混合一起,但是你明白了。你可以在一个类中处理事件,订阅服务器可能是你的表单,然后线程和处理将在你的类中进行大小计算

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

    }
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统图;
使用系统文本;
使用System.Windows.Forms;
使用系统线程;
命名空间ThreadWithDataReturnExample
{
公共部分类Form1:Form
{
私有线程thread1=null;
公共表格1()
{
初始化组件();
thread1=新线程(新的ThreadStart(this.threadEntryPoint));
Thread1Completed+=新的AsyncCompletedEventHandler(thread1\u Thread1Completed);
}
私有无效开始按钮单击(对象发送者,事件参数e)
{
thread1.Start();
//或者,您可以传递一些对象
//例如启动(someObject);
//具有适当的锁定,或协议,其中
//在之前,没有其他线程访问该对象
//线程完成时发出事件信号,
//引用该对象的任何其他类
//将能够访问该数据。
//但是,我将使用AsyncCompletedEventArgs
//在标志着完成的事件中
}
void thread1\u thread1已完成(对象发送方,AsyncCompletedEventArgs e)
{
if(this.invokererequired)
{//如果我们不在GUI线程上,请封送调用
BeginInvoke(新的AsyncCompletedEventHandler(线程1\u线程1已完成),
新奥布杰
class DoSomethingInBackground
{
    BackgroundDoerOfSomething _doer;

    void DoSomething()
    {
        _doer = new BackgroundDoerOfSomething("abc");
        _doer.RunWorkerCompleted += _doer_RunWorkerCompleted;
        _doer.RunWorkerAsync();
    }

    void _doer_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        var myResult = _doer.SomeResult;
        // then do something with the result
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace QXBackup
{
    class main
    {
        static void Main(string[] args)
        {
            var bgWorker = new BackgroundWorker();
            bgWorker.WorkerReportsProgress = true;

            bgWorker.DoWork += (sender, e) =>
            {
                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);
            };

            bgWorker.RunWorkerCompleted += (sender, e) => Console.WriteLine("completed...");
            bgWorker.ProgressChanged += (sender, e) => Console.WriteLine("progressing...");


            bgWorker.RunWorkerAsync();
        }
    }
}
static void Main(string[] args)
{
    lacie BackupDrive = new lacie();
    BackupDrive.findLacie();

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

    size BackupSize = new size();
    System.Threading.ThreadPool.QueueUserWorkItem(s =>
    {
        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);
}
System.Threading.ThreadPool.QueueUserWorkItem(s =>
{
    while (true)    // might want a real condition like while(!backupNotDone)
    {
        int SizeofBackup = (int) (((BackupSize.BackupSize)/1024f)/1024f)/1024;
        Console.WriteLine("Backup Size: " + Convert.ToString(SizeofBackup + "G"));
    }
});