65.9K
CodeProject 正在变化。 阅读更多。
Home

多线程链式任务队列

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.43/5 (5投票s)

2009 年 4 月 30 日

CPOL
viewsIcon

38637

downloadIcon

891

我需要一个多线程的任务队列,但任务之间需要链接,所以我创建了这个多线程任务队列。

Task_Queue_Demo.jpg

引言

这里解释的类演示了一个多线程的链接任务队列。这个类允许你将多个任务添加到多个队列中。两个队列可以同时在不同的线程中运行,但每个队列将一次运行一个任务,并且一个接一个地运行。

背景

我曾经遇到一个项目,需要执行大量的占用处理器资源的任务,例如复制文件、压缩和加密等。因此,我创建了这个易于使用的框架来排队任务并显示其状态。这里的演示项目是匆忙创建的,并没有演示类的所有功能。

ClassDiagram1.jpg

使用代码

要使用这段代码,首先在你的表单或类中添加 TaskQueue 成员变量,然后在初始化代码中,使用 TaskQueueTable 类创建队列。就像下面这样..

protected TaskQueue taskQueue;
public frmQueueDemo()
{
    InitializeComponent();
    taskQueue = TaskQueueTable.Instance.GetTaskQueue("Encryption");
    taskQueue.TaskStarting += 
     new TaskQueue.TaskStartingEeventHandler(taskQueue_TaskStarting);
}

然后,继承 Task 类来创建你的类,并重写 PerformTask 函数。就像这样..

public class EncriptFileTask : Task
{
    public EncriptFileTask(string filePath) : 
           base("Encripting file " + filePath)
    {
        this.FilePath = filePath;
    }
    private string filePath;
    public string FilePath {
        get
        {
            return filePath;
        }
        set
        {
            filePath = value;
        }
    }
    protected override void PerformTask(object param)
    {
        try
        {
            FileStream reader = File.OpenRead(FilePath);
            RC4.rc4_key key = new RC4.rc4_key();
            RC4.PrepareKey(System.Text.UTF8Encoding.ASCII.GetBytes(
                           "Task Queue Demo"), ref key);

            RC4 rc4 = new RC4();
            byte[] read = new byte[8];
            long total = reader.Length;
            long completed = 0;
            while(reader.Position < total && !IsAborting)
            {
                int bRead = reader.Read(read, 0, 8);
                completed += bRead;
                RC4.rc4(ref read, bRead, ref key);
                int percent = (int)((completed / (double)total) * 100);
                //if(percent > 0) OnAddLog("Percent " + percent);
                OnProgress(percent);
            }
            reader.Close();
        }
        catch (Exception ex)
        {
            OnAddLog(ex.Message);
        }
        base.PerformTask(param);
    }
}

请记住调用 base.PerformTask 函数,以确保在任务完成时调用适当的事件。 另外请记住使用 IsAborting 属性来允许和平地取消任务。

© . All rights reserved.