c# – 使用队列创建BackgroundWorker

栏目: ASP.NET · 发布时间: 7年前

内容简介:翻译自:https://stackoverflow.com/questions/15119974/creating-backgroundworker-with-queue

我需要创建队列并将其与BackgroundWorker一起使用.所以我可以添加操作,然后在下一步完成时将在后台启动.我通过谷歌找到了这个代码:

public class QueuedBackgroundWorker<T>
{
    public void QueueWorkItem(
        Queue queue,
        T inputArgument,
        Func<T> doWork,
        Action workerCompleted)
    {
        if (queue == null) throw new ArgumentNullException("queue");

        BackgroundWorker bw = new BackgroundWorker();
        bw.WorkerReportsProgress = false;
        bw.WorkerSupportsCancellation = false;
        bw.DoWork += (sender, args) =>
        {
            if (doWork != null)
            {
                args.Result = doWork(new DoWorkArgument<T>((T)args.Argument));
            }
        };
        bw.RunWorkerCompleted += (sender, args) =>
        {
            if (workerCompleted != null)
            {
                workerCompleted(new WorkerResult<T>((T)args.Result, args.Error));
            }
            queue.Dequeue();
            if (queue.Count > 0)
            {
                QueueItem<T> nextItem = queue.Peek() as QueueItem<T>;
                nextItem.BackgroundWorker.RunWorkerAsync(nextItem.Argument);
            }
        };

        queue.Enqueue(new QueueItem<T>(bw, inputArgument));
        if (queue.Count == 1)
        {
            QueueItem<T> nextItem = queue.Peek() as QueueItem<T>;
            nextItem.BackgroundWorker.RunWorkerAsync(nextItem.Argument);
        }
    }
}

public class DoWorkArgument<T>
{
    public DoWorkArgument(T argument)
    {
        this.Argument = argument;
    }
    public T Argument { get; private set; }
}

public class WorkerResult<T>
{
    public WorkerResult(T result, Exception error)
    {
        this.Result = result;
        this.Error = error;
    }

    public T Result { get; private set; }
    public Exception Error { get; private set; }
}

public class QueueItem<T>
{
    public QueueItem(BackgroundWorker backgroundWorker, T argument)
    {
        this.BackgroundWorker = backgroundWorker;
        this.Argument = argument;
    }

    public T Argument { get; private set; }
    public BackgroundWorker BackgroundWorker { get; private set; }
}

但我有doWork和workerCompleted的问题.我收到错误:

Delegate ‘Func’ does not take 1 arguments

我怎样才能解决这个问题?我该如何更改参数?谢谢

这是一个更短的方法,可以满足您的需求:

public class BackgroundQueue
{
    private Task previousTask = Task.FromResult(true);
    private object key = new object();
    public Task QueueTask(Action action)
    {
        lock (key)
        {
            previousTask = previousTask.ContinueWith(t => action()
                , CancellationToken.None
                , TaskContinuationOptions.None
                , TaskScheduler.Default);
            return previousTask;
        }
    }

    public Task<T> QueueTask<T>(Func<T> work)
    {
        lock (key)
        {
            var task = previousTask.ContinueWith(t => work()
                , CancellationToken.None
                , TaskContinuationOptions.None
                , TaskScheduler.Default);
            previousTask = task;
            return task;
        }
    }
}

通过添加每个新动作作为前一个的延续,您确保一次只能处理一个,因为下一个项目在上一个项目完成之前不会启动,您确保在那里没有任何线程坐在空闲处没有什么可以解决的,你确保他们都按顺序完成.

另请注意,如果您认为自己只需要一个队列而不需要任何数字,那么您可以将所有成员设置为静态,但这取决于您.

翻译自:https://stackoverflow.com/questions/15119974/creating-backgroundworker-with-queue


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Kotlin程序员面试算法宝典

Kotlin程序员面试算法宝典

孙伟、楚秦 / 机械工业出版社 / 2018-12 / 69

本书是一本讲解程序员面试笔试算法的书籍。在写法上,除了讲解如何解答算法问题以外,还引入了例子辅以说明,以便读者能够更加容易地理解。 本书将程序员面试笔试过程中的各类算法类真题一网打尽。在题目的广度上,通过各种渠道,搜集了近3年来几乎所有IT企业面试笔试算法高频题目,所选择题目均为企业招聘使用题目;在题目的深度上,本书由浅入深、庖丁解牛式地分析每一个题目,并提炼归纳,同时,引入例子与源代码、时......一起来看看 《Kotlin程序员面试算法宝典》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具