I have a big long looping procedure like this:
public void Process()
{
bool done = false;
do {
//do stuff
}while (!done);
}
that I'd like to chop into bits and have the calling routine display my progress in some sort of UI. It's a class library, so the caller may be anything (Console App, WinForms, WebApp, ...).
It would be easiest if I could do:
public void Process()
{
bool done = false;
do {
//do stuff
yield return;
}while (!done);
}
So the caller could keep calling the method until it's done.
This smells more like a job for BackgroundWorker, but that seems "wrong" for a Console App... I won't always NEED multithreading. Or does it? I mean, yeah, I could just have the console's main thread just wait for it to finish.
My question is: Can I use the "piecemeal" deferred execution functionality of "yield return" without actually returning something?
It specifies that an iterator has come to an end. You can think of yield break as a return statement which does not return a value.
The yield return statement returns one element at a time. The return type of yield keyword is either IEnumerable or IEnumerator .
1. "yield break" breaks the Coroutine (it's similar as "return"). "yield return null" means that Unity will wait the next frame to finish the current scope. "yield return new" is similar to "yield return null" but this is used to call another coroutine.
The language feature you want is called a coroutine (or, more precisely, a semicoroutine, but let's not be pedantic.) C# iterator blocks are a weak form of coroutine. I recommend against making "dummy" sequences just because you want coroutines.
The await
operator in C# 5 is also a form of coroutine and might more closely resemble your desired solution, particularly if your operation is logically an asynchronous, high-latency operation. There are standard patterns for progress reporting with asynchronous coroutines in C# 5; I would start by reading this:
http://blogs.msdn.com/b/dotnet/archive/2012/06/06/async-in-4-5-enabling-progress-and-cancellation-in-async-apis.aspx
In short, no.
yield return
has to return something.
http://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx
The Process
method should have a return type of IEnumerable
, IEnumerable<T>
, IEnumerator
, or IEnumerator<T>
. You may return dummy objects
if you really want to use yield
.
You might want to investigate different ways to report progress to the caller.
As already someone else answered, no that's not the way to go, but why don't you simply use a callback Func
or Action
or something to let the callee interact with your loop?
public void Process(Action callback)
{
bool done = false;
do {
//do stuff
callback();
}while (!done);
}
Or use some other kind of event handling which is typically used for stuff like that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With