Lib*_*tal 8 c# generics queue wpf backgroundworker
我需要创建队列并将其与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的问题.我收到错误:
委托'Func'不带1个参数
我怎样才能解决这个问题?我该如何更改参数?谢谢
Ser*_*rvy 31
这是一个更短的方法,可以满足您的需求:
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;
        }
    }
}
通过添加每个新操作作为前一个的延续,您确保一次只处理一个,因为下一个项目在上一个项目完成之前不会启动,您确保在那里没有任何线程坐在空闲处没有什么可以处理的,你确保它们都按顺序完成.
另请注意,如果您认为自己只需要一个队列而不需要任何号码,那么您可以成为所有成员static,但这取决于您.
| 归档时间: | 
 | 
| 查看次数: | 11307 次 | 
| 最近记录: |