0

I have a simple BackgroundWorker that should generate results, but I don't know how to get them back to my calling method. I have read a number of answers, and they all show me how the RunWorkerCompleted event can receive the results of the DoWork event handler, and to prove this they show a message box with the result. That's all good, but how do I get a result back to the actual method that called RunWorkerAsync?

myResult=myBackGroundWorker.RunWorkerAsync(); // This obviously doesn't compile

This answer in particular has been very useful:

How to make BackgroundWorker return an object

but I still don't know how to access the results. This answer also mentions the use of a delegate:

BackgroundWorker Return A Value?

but I don't understand if this would solve my problem, or if I would still just get the result inside the RunWorkCompleted event handler.

AlePorro
  • 111
  • 1
  • 11
  • 1
    If you want it like this I would recommend a `Task`, and `await` it. – Stefan Jul 14 '19 at 17:36
  • 1
    You cannot get it back to the `RunWorkerAsync` call without hacking that to work. The `RunWorkerAsync` only _starts_ the worker, when it's done it invokes a callback. What you want would screw up the purpose because you would need to wait for that background worker which is exactly what the callback is supposed to make unnecessary. For your functionality you should have a look at async/await. – Joelius Jul 14 '19 at 17:40
  • The easiest way is to use ReportProgress. You can return a state object which can return one or more objects. See msdn : https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.backgroundworker.reportprogress?view=netframework-4.8 – jdweng Jul 14 '19 at 18:20
  • Your question makes zero sense. The whole point of a class like `BackgroundWorker`, and its method `RunWorkerAsync()`, is that you call that method when you want the background work to be done **in the background**. By definition, that means the work is **not yet complete** when the `RunWorkerAsync()` method returns. How could that method possibly return the result of the work, given that the **entire point** of the method is to return before the result of the work is available? – Peter Duniho Jul 14 '19 at 18:47
  • @PeterDuniho I clearly had not understood correctly the usage of backgroundworker but I don't think I didn't make *any* sense... In the end I just wanted to get back a result from a background operation, which, as many others have more constructively pointed out, can be achieved using tasks and async/await. – AlePorro Jul 14 '19 at 19:07
  • _"I just wanted to get back a result from an operation"_ -- that's not what your question says. You stated you already know how to get the result back from `BackgroundWorker`, i.e. with `RunWorkerCompleted`. If _all_ you wanted was to get back a result, you already knew how to do that. No, your question specifically asked to have `RunWorkerAsync()` return a value, which makes zero sense. – Peter Duniho Jul 14 '19 at 19:11

1 Answers1

3

Short answer: you can't.


Think about what it means to return the value back to the method that called RunWorkerAsync. This would mean that the method has to pause its execution, wait for the background worker to complete its work, then continue again. But you still want other methods to run during the waiting, otherwise the UI would freeze.

Does that sound familiar to you? That's basically what an async method does when it encounters an await expression!

BackgroundWorker is quite an old API, and there wasn't the fancy feature of async/await when it came out (async/await is a language feature anyway), which is why it uses events to do the trick. Back then, there wasn't a way to do an operation asynchronously, and return a value back to the caller elegantly.

Now that we have async/await, you can use it to do what you want:

someReuslt = await Task.Run(() => { ... });

If you haven't heard about async/await at all, this is a good place to start.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • 1
    Thank you, clearly I was trying to use the wrong approach. I will have a good read at async/await and try that. – AlePorro Jul 14 '19 at 19:08