Creating BackgroundWorker with Queue(使用队列创建 BackgroundWorker)
问题描述
我需要创建队列并将其与 BackgroundWorker 一起使用.所以我可以添加操作,下一个完成时在后台启动.我通过谷歌找到了这段代码:
I need to create queue and use it with BackgroundWorker. So I can add operations and when one is done next is starting in background. I found this code by google:
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 有疑问.我得到错误:
But I have problem with doWork and workerCompleted. I get error:
Delegate 'Func' 不接受 1 个参数
Delegate 'Func' does not take 1 arguments
我该如何解决这个问题?我应该如何更改参数?谢谢
How can I fix this? How should I change parameters? Thanks
推荐答案
这是一个更短的方法,可以满足您的需求:
Here's a much shorter method that does what you want:
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;
}
}
}
通过添加每个新动作作为前一个动作的延续,您可以确保一次只处理一个动作,因为在前一个项目完成之前下一个项目不会开始,您可以确保没有线程闲置无事可做时闲置,并确保它们都按顺序完成.
By adding each new action as a continuation of the previous you ensure that only one is worked on at a time, as the next item won't start until the previous item is finished, you ensure that there is no thread sitting around idling when there is nothing to be worked on, and you ensure they're all done in order.
另外请注意,如果您认为只需要一个队列而不是任何数量,您可以将所有成员设为 static
,但这取决于您.
Also note that if you only ever think you'll need one queue, and not any number, you could make all of the members static
, but that's up to you.
这篇关于使用队列创建 BackgroundWorker的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:使用队列创建 BackgroundWorker


- 输入按键事件处理程序 2022-01-01
- 带有服务/守护程序应用程序的 Microsoft Graph CSharp SDK 和 OneDrive for Business - 配额方面返回 null 2022-01-01
- 如何用自己压缩一个 IEnumerable 2022-01-01
- 在哪里可以找到使用中的C#/XML文档注释的好例子? 2022-01-01
- Web Api 中的 Swagger .netcore 3.1,使用 swagger UI 设置日期时间格式 2022-01-01
- C# 中多线程网络服务器的模式 2022-01-01
- MoreLinq maxBy vs LINQ max + where 2022-01-01
- WebMatrix WebSecurity PasswordSalt 2022-01-01
- C#MongoDB使用Builders查找派生对象 2022-09-04
- 良好实践:如何重用 .csproj 和 .sln 文件来为 CI 创建 2022-01-01