在集合项中使用的BackgroundWorker
我使用了 Backgroudworker 来完成一些工作,以便完成一些耗时的任务。
public void ConnectDataProvider()
{
bgw = new BackgroundWorker();
bgw.DoWork += new DoWorkEventHandler(bgw_DoWork);
bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);
}
另一种方法启动后台工作程序:
public void StartPolling()
{
bgw.RunWorkerAsync();
}
然后我进行了事件处理:
void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// do it over again
StartPolling();
}
void bgw_DoWork(object sender, DoWorkEventArgs e)
{
// do work
WriteData();
}
如您所见,我在完成后重新启动了工作程序。 现在这适用于单个后台工作者。
现在我想要一个集合,并且每个项目都应该执行此任务。 然而,根据上面的概念,它只会在第一个启动的工作程序中继续运行,因为它会重新启动工作程序。 我在想,也许结合使用计时器可以解决这种情况,为其他工作线程提供方式。
BackgroundWorker 仍然是一个不错的选择吗? 像我一样重用BackgroundWorker 是很常见的吗?
编辑1:澄清:我面临的问题是,我需要用自己的BackgroundWorker 来管理每个集合。 我正在考虑一个计时器,以定期从每个项目发出请求。 这就是我被困住的地方。
编辑2:查看我自己的答案,我没有解决这个问题,但发现我可以与计时器一起得到我想要的东西。
编辑3:为了澄清(另一次尝试,我不擅长)我想要实现的目标:我有跟踪对象,用于 GPS 跟踪。 我想跟踪一大堆,所以每个跟踪设备一个对象。 他们都需要经常进行民意调查。 我为单个测试对象设置了一个BackgroundWorker。 我喜欢后台工作人员在完成时告诉我的方式。 但我无法让它与所有跟踪对象一起工作。
现在每个跟踪对象都有自己的计时器。 该计时器生成一个新线程并执行耗时的工作(我将其命名为 DoWrite)。 不需要BackgroundWorker,因为我处理计时器,然后创建一个新计时器。 这就是它的全部作用。
I used a Backgroudworker to do some work in order to do some time consuming tasks.
public void ConnectDataProvider()
{
bgw = new BackgroundWorker();
bgw.DoWork += new DoWorkEventHandler(bgw_DoWork);
bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);
}
Another method starts the background worker:
public void StartPolling()
{
bgw.RunWorkerAsync();
}
Then I did the event handling:
void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// do it over again
StartPolling();
}
void bgw_DoWork(object sender, DoWorkEventArgs e)
{
// do work
WriteData();
}
As you can see, I started the worker over on completion. Now this works for a single backgroundworker.
Now I want a collection, and each item should perform this task. However with the concept above it will just keep on running in the first worker started, as it starts the worker over. I'm thinking, maybe a Timer in combination could solve the situation to give the other worker threads way.
Is the BackgroundWorker still a good choice? Is it common to reuse the BackgroundWorker like I did?
EDIT 1: To clairify: The problem I'm facing is, that I need manage the collection each with their own BackgroundWorker. I was thinking about a timer, to set off request periodically from each item. This is where I'm stuck.
EDIT 2: See my own answer, I didn't solve this issue, but found that I can go along with timers to get what I wanted.
EDIT 3: To clarify (another try, I'm not good at that) what I wanted to achieve: I've got tracking objects, for gps tracking. I want to track a whole bunch of them, so one object per tracking device. They all need to be polled frequently. Ihad a BackgroundWorker set up for a single test object. I liked they way the Backgroundworker would tell me when it's done. But I couldn't get it working with all of the tracking objects.
Now every tracking object has its own timer. This timer spawns a new thread and does the time consuming work (which I named DoWrite). No BackgroundWorker needed, as I dispose the timer and then create a new timer. That's all it does.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
其中可能有多少个? 您应该小心地在集合中的项目和线程之间创建 1:1 关系。 另一个编码员可能会出现并比您计划的更多地扩展此集合。
对于这样的事情,我通常喜欢只使用一个线程和一个队列 - 因此事件只是将需要完成的工作放入 ConcurrentQueue 中,如果线程未运行,则启动该线程,并搅动排队的工作,直到它完成为止。没有事情可做,然后就死了。 下次有更多工作发生时,该事件将检查线程是否正在运行并启动它。
它更便宜,因为如果发生很多事情,您只运行一个线程,而不是停止和启动很多线程,或者如果发生的事情很少,则一个线程几乎从不运行。
How many of these might there be? You should be careful of creating a 1:1 relationship between items in a collection and threads. Another coder might come along and expand this collection more than you planned.
For things like this I usually like to use just the one thread, and a queue - so the events just put the work that needs to be done in a ConcurrentQueue, and the thread starts if not running, and churns through the queued work until it's out of things to do, and dies. The next time more work comes in the event will check if the thread is running and start it.
It's cheaper because if there's a lot going on, you run just the one thread instead of stopping and starting a lot of them, or if there's very little going on, the one thread is almost never running.
如果您只是在 Dowork() 中放置一个 while() 循环,也许还有一点 Sleep(),那么您的解决方案看起来会更合乎逻辑。
然后就不会反对运行多个 Bgw,尽管您可能看不到很大的速度优势。
Your solution would look more logical if you just put a while() loop in Dowork(), maybe with a little Sleep().
And then there would be no objection against running multiple Bgw's, although you may not see a great speed benefit.
您可以完全按照您所描述的方式进行操作 - 只需确保将相关后台工作程序的引用传递给 StartPolling 即可,因此:
那么显然,您需要管理 BackgroundWorker 的集合代码>相应地。
You can do exactly what you describe--just make sure that you pass the reference to the relevant background worker to
StartPolling
, thusly:Then obviously, you need to manage the collection of
BackgroundWorker
's accordingly.为什么不使用 Progresschanged 事件? 您可以使用用户状态对象来传递数据。
在工作中,只需池化设备,并在过程中更改将数据发送到 UI 线程。
无限地执行此操作,然后使用取消来停止该线程。
问候。
Why don't you use the progresschanged event? You could use the userstate object for passing data.
In do work just pool the devices, and in process changed send the data to the UI thread.
Do it in a endless while and use cancel to stop that thread.
Regards.
当您同时执行多个耗时任务时,我建议您使用线程池
http://msdn.microsoft.com/en-us/library/ms973903.aspx
When you have multiple time consuming tasks to be executed in the same time, I suggest you to use Thread Pool
http://msdn.microsoft.com/en-us/library/ms973903.aspx
由于到目前为止还没有人这样做,所以我将引入计时器方法。 我尝试将两者(BackgroundWorker 和 Timer)结合起来,但这没有意义。
我想要一种允许多个实例通过线程请求数据的机制。 另外,我想要中间有一些间隔。
因此,在尝试之后,我认为我只能使用计时器方法:
这就是约翰·桑德斯在类似(但不同)问题上的建议。 似乎可以完成这项工作。
WriteData()
有一个同步 HttpWebRequest,因此它可以处理超时。我现在的问题是:计时器对象的新实例化有多昂贵?我的意思是:有更好的方法来实现这一点吗?
注意:WebRequest 的异步方法不起作用,我尝试过。 到目前为止我不知道这是否是服务器的一种方式。
Since nobody did it so far, I'll throw in the timer approach. I tried to combine the two (BackgroundWorker and Timer), but that didn't make sense.
I wanted a mechanism to allow multiple instances to request data by thread. Also, I wanted some interval in between.
So after trying around, I figured I could get along with a Timer-approach only:
That was what John Saunders suggested on a similar (but different) problem. It seems to do the job. The
WriteData()
has a synchronous HttpWebRequest, so it can handle a timeout.My question now is: How expensive is the new instantiation of the timer object? By how expensive I mean: Are there better ways to achieve that?
Note: The asynchronous approach of the WebRequest won't work, I tried that. I have no clue so far, if that is a manner of the server.