[英]Should I use a Backround worker or write my own threads
So we have a program that has a pause button in the main UI. 因此,我们有一个程序在主界面中具有暂停按钮。 When the pause button is pressed a time stamp is saved and when pressed again another timestamp is then created, the time diff between the two is calculated and then then all 3 values along with a user name are sent to a db using WebClient
. 当按下暂停按钮时,将保存一个时间戳,然后再次创建另一个时间戳,将计算两者之间的时间差,然后使用WebClient
将所有3个值和用户名一起发送到db。 The problem is that if the button is pressed multiple times rapidly the there are issues with getting all the data sent. 问题是,如果快速多次按下按钮,则发送所有数据都会出现问题。
I had the idea to make a queue and instead of the pause button sending the data it would write it to a queue and then have a separate thread check the queue and handle the handle the sending. 我有一个创建队列的想法,而不是发送数据的暂停按钮,而是将其写入队列,然后让一个单独的线程检查队列并处理发送的句柄。
Using a timer to fire a background worker every x-seconds for the simple task of reading a queue and sending data if its there feels like overkill/abuse. 使用计时器每隔x秒触发后台工作人员一项简单的任务,即读取队列并发送数据(如果感觉过分/滥用)。 Am I right and this is more of regular thread kind of job or is the background worker the way to go? 我是对的,这更多是常规线程的工作,还是后台工作者要走的路?
I would use a ConcurrentQueue wrapped in a BlockingCollection class, and use a Task to watch the collection. 我将使用包装在BlockingCollection类中的ConcurrentQueue,并使用Task来监视集合。
var pendingEntries = new BlockingCollection<List<Entry>>(new ConcurrentQueue<List<Entry>>());
var loggingTask = System.Threading.Tasks.Task.Factory.StartNew(ConsumerTask, pendingEntries);
The class Entry is a container for whatever you want to record at once. Entry类是您想要一次记录的任何内容的容器。
The consumer task looks like this: 使用者任务如下所示:
private void ConsumerTask(object parameter)
{
var localPendingEntries = (BlockingCollection<List<Entry>>)parameter;
foreach (var entry in localPendingEntries.GetConsumingEnumerable())
{
// push the 'entry' where you want.
}
}
To add entries to the queue do this: 要将条目添加到队列,请执行以下操作:
var newEntry = new Entry(......);
pendingEntries.Add(newEntry);
When you are done adding entries, call this: 完成添加条目后,请调用此命令:
pendingEntries.CompleteAdding();
The task will fall out of the foreach loop once it has finished processing the entries currently in the queue. 一旦完成处理当前队列中的条目,该任务将脱离foreach循环。
You can then wait for the task to complete with: 然后,您可以等待任务完成:
loggingTask.Wait();
pendingEntries.Dispose();
I personally use threads. 我个人使用线程。 Backgroundworkers take up too much code for me. 后台工作人员为我占用了太多代码。 If you have the thread as a global variable, you can kill or start the thread at will. 如果将线程作为全局变量,则可以随意终止或启动线程。
Take a look here: BackgroundWorker vs background Thread 在这里看看: BackgroundWorker vs background Thread
For both a thread and backgroundworker you're able to see if they're running. 对于线程和后台工作人员,您都可以查看它们是否正在运行。 If they're running then you're able to either disable the button if it's running or make it so the button does nothing. 如果它们正在运行,则可以禁用该按钮(如果正在运行)或启用它,以便该按钮不执行任何操作。 For what you're doing, I recommend background worker. 对于您正在执行的操作,我建议背景工作者。
protected void btnPause_Click(object sender, EventArgs e)
{
System.ComponentModel.BackgroundWorker disableWorker = new System.ComponentModel.BackgroundWorker();
disableWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(disableWorker_DoWork);
disableWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(disableWorker_RunWorkerCompleted);
disableWorker.RunWorkerAsync();
}
void disableWorker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
btnPause.Enabled = true;
}
void disableWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
btnPause.Enabled = false;
System.Threading.Thread.Sleep(10000);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.