C# 在BackgroundWorker 中异步工作?
我不是最擅长多线程,这有点复杂,所以希望我能很好地解释它。
基本上,我有一个BackgroundWorker任务,里面有几个从网站检索信息的调用。可能有更好的方法来做到这一点,但我想不出一个。我这样做的原因是因为我希望在所有对网站的调用(以及后续的信息处理)完成时有一个事件。
这基本上就是我正在做的事情:
private void loadContent() {
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += delegate(object sender, DoWorkEventArgs e) {
getAndProcessInformation(desiredInformationName);
getAndProcessInformation(someOtherDesiredInformationName);
};
worker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e) {
MessageBox.Show("Finished!");
Dispatcher.BeginInvoke(() => { progressBar(false); });
};
worker.RunWorkerAsync();
}
private void getAndProcessInformation(string theInformationIWant){
Fetcher dataFetcher = new Fetcher(); //Fetcher is a custom class that reads information from a web server
dataFetch.receivedData += delegate(DataResponseArgs args) {
//Process some data
};
dataFetch.requestData(theInformationIWant);
}
所以,发生的情况是,在调用两个 getAndProcessInformation 方法之后、在数据实际完成处理之前,立即调用 RunWorkerCompleted 。有什么方法可以让 RunWorkerCompleted 仅在方法中的处理实际完成后运行?
现在,我可以看到,BackgroundWorker 并不是真正必要的,因为处理实际上已经在单独的线程中完成,但我不知道有任何替代方案可以让我获得在所有事件都触发一个事件时获得所需的结果。的处理已经完成。所以,我想这实际上是两个问题;我应该继续使用BackgroundWorker吗?如果是这样,我该如何修复它,或者如果不是,有什么替代方案?
I'm not the best with multi-threading, and this is a bit complicated, so hopefully I can explain it well.
Basically, what I have is a BackgroundWorker task, and inside it are several calls to retrieve information from a website. There may be a better way to do this, but I can't think of one. The reason I'm doing this is because I want to have a single event for when all of the calls to the website (and the subsequent processing of the information) are completed.
This is basically what I have going on:
private void loadContent() {
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += delegate(object sender, DoWorkEventArgs e) {
getAndProcessInformation(desiredInformationName);
getAndProcessInformation(someOtherDesiredInformationName);
};
worker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e) {
MessageBox.Show("Finished!");
Dispatcher.BeginInvoke(() => { progressBar(false); });
};
worker.RunWorkerAsync();
}
private void getAndProcessInformation(string theInformationIWant){
Fetcher dataFetcher = new Fetcher(); //Fetcher is a custom class that reads information from a web server
dataFetch.receivedData += delegate(DataResponseArgs args) {
//Process some data
};
dataFetch.requestData(theInformationIWant);
}
So, what happens is that the RunWorkerCompleted is called right after the two getAndProcessInformation methods are called, and before the data is actually finished processing. Is there any way I can make RunWorkerCompleted only run once the processing in the methods is actually finished?
Now, I can see that the BackgroundWorker isn't really necessary, since the processing is actually already being done in a separate thread, but I don't know any alternative that would let me get the desired result of having one event triggered when all of the processing has been completed. So, I guess this is really two questions; Should I continue using the BackgroundWorker, and, if so, how do I fix it, or, if not, what's the alternative?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您的 Fetcher 已经创建了自己的线程,那么使用 BackgroundWorker 并没有像您已经想到的那样有多大意义。
由于您还没有分享 Fetcher 的实现。如果您想坚持使用已有的内容,那么它可能应该是这样的。
这样,函数 getAndProcessInformation 在处理完成之前不会返回。一次只有一个 Fetch 正在工作。
如果您希望所有 Fetcher 并行工作,则需要删除 WaitOne 并让 getAndProcessInformation 返回等待句柄。然后在 DoWork 中,您可以等待所有句柄收到信号。
If your Fetcher is already creating its own thread, Using BackgroundWorker doesn't make much of a sense like you already figured out.
As you have not shared the implementation of Fetcher. It should probably be something like this if you want to stick with what you already have
This way the function getAndProcessInformation wont return until processing has been done. Only one Fetch will be working at a time.
If you want all Fetchers to work in parallel, you have remove the WaitOne and have the getAndProcessInformation return the wait handle. Then in DoWork you can do one wait for all handles to be signalled.