If I call methodA and then methodB output is: "121234". But I need output: "1234", "12" from methodA and "34" from methodB. I need to remember where getNumber ended with the return, and the next call continue from here. It is possible?
MethodA snipset
int x = 0;
foreach (var num in GetNumber())
{
if (x == 2)
{
break;
}
x++;
Console.Write(num);
}
MethodB snipset
int x = 0;
foreach (var num in GetNumber())
{
if (x == 4)
{
break;
}
x++;
Console.Write(num);
}
GetNumber
static IEnumerable<int> GetNumber()
{
int x = 0;
while (true)
{
yield return x++;
}
}
You can initialize x outside the method:
static class InfiniteContinuingSequence
{
static int x = 0;
public static IEnumerable<int> GetNumbers()
{
while (true)
{
yield return x++;
}
}
}
But you will have to explicitly be careful when and where this sequence gets enumerated. If it is inadvertently enumerated multiple times, you will "lose" numbers in the sequence; if you try to exhaustively enumerate GetNumbers() you'll get either an infinite loop or an overflow; and if you try to call this from multiple threads without locking, you'll get potentially odd behavior.
Instead, I might suggest to either use an explicit enumerator, or be able to specify a "restart point" to your method (in this case at least you will not get odd behavior by multiple enumerations):
static IEnumerable<int> GetNumbers(int startingPoint = 0)
{
int x = startingPoint;
while (true)
{
yield return x++;
}
}
Change GetNumber to
static int x = 0;
static IEnumberable<int> GetNumber()
{
while (true) { yield return x++; }
}
The issue is that you have two enumerations of GetNumber. By making x static you will get the results you want. But beware this is not thread safe code.
Related
For my application, I have built an iterator and I need to use each of the values it yields along with the previous one.
For example, consider the following iterator, that yields the first terms of the Fibonacci sequence:
public static IEnumerable<int> GetFibonacciNumbers(int count)
{
int a = 0;
int b = 1;
int i = 0;
while (i < count)
{
yield return a;
int temp = a;
a = b;
b = temp + b;
i++;
}
}
Now I want to use this enumerator to compute increasingly accurate estimates of the golden ratio, which means I need to use the yielded value along with the previous one. The following approach kind of works:
static void Main(string[] args)
{
int fib0 = 0;
foreach (int fib1 in GetFibonacciNumbers(10))
{
var phi = (double)fib1 / fib0;
Console.WriteLine(phi);
fib0 = fib1;
}
}
The issues are that the first value for phi is wrong, as the first value for fib0 used isn't actually part of the sequence.
Just return both the current and previous values from your iterator:
public static IEnumerable<(int prevValue, int currentValue)> GetFibonacciNumbers(int count)
{
int a = 0;
int b = 1;
int i = 0;
while (i < count)
{
yield return (a, b);
int temp = a;
a = b;
b = temp + b;
i++;
}
}
The above uses C# 7.0 Tuple Syntax, but you can easily convert it to use a regular Tuple<int, int> as well.
You can have the enumerating function keep track of the previous and current values and return them as a tuple. For example, in the fibonacci example it would be something like this:
static IEnumerable<(int Previous, int Current)> GetFibonacciNumbers(int count)
{
var (previous, current) = (0, 1);
for(int i = 0; i < count; i++)
{
yield return (previous, current);
(previous, current) = (current, previous + current);
}
}
Haim770's answer is correct if you want to modify your generator. However, you might also want to use a general purpose method that you can then reuse with any IEnumerable<T>:
public static IEnumerable<(T prevValue, T currentValue)> OverlappingPairs<T>(IEnumerable<T> source)
{
bool first = true;
T previous = default;
foreach (var item in source)
{
if (!first)
yield return (previous, item);
first = false;
previous = item;
}
}
(And of course, if you add this before the parameter and put it in a static class, it'll work as an extension method)
Some fibonacci sequences start with 1 and 1 instead of 0 and 1. So maybe that could solve your problem.
I am working with an API that uses functions that use out parameters. I want to use the value in one of these out parameters in a while loop. For example:
static int counter = 0;
static void getCounterValue(out int val)
{
val = counter;
counter++;
}
static void Main()
{
// Right now, I'm having to do this:
int checkVal = 0; // I have to figure out an appropriate starting value.
while (checkVal < 10)
{
getCounterValue(out checkVal);
Console.WriteLine("Still waiting.");
}
Console.WriteLine("Done.");
}
Is there a simpler syntax to do this? I want something more classic like while (getCounterValue() < 10), but I have to deal with the out parameters because it's an API that I can't change.
You can't do anything directly, the return value of the method call is what while will use and that can't be the value you want. If this is causing you problems, you can always wrap the method call:
int wrappedGetCounterValue()
{
int i;
getCounterValue(out i);
return i;
}
Or with C# 7:
int wrappedGetCounterValue()
{
getCounterValue(out int i);
return i;
}
And use that in your while loop.
while (wrappedGetCounterValue() < 10)
....
do
{
getCounterValue(out checkVal);
Console.WriteLine("Still waiting.");
} while (checkVal < 10)
You can use the infinite loop with break condition:
while (true)
{
int checkVal;
getCounterValue(out checkVal);
if (10 <= checkVal)
break;
Console.WriteLine("Still waiting.");
}
Note the difference between do..while (checkVal < 10) option is that you will not output "Still waiting" message if first counter value will be greater or equal to 10. You cannot do that with do..while loop unless you will duplicate loop break condition (checkVal < 10).
Another option (but with the cost of code duplication) is to use for loop:
int checkVal;
for (getCounterValue(out checkVal); checkVal < 10; getCounterValue(out checkVal))
{
Console.WriteLine("Still waiting.");
}
Console.WriteLine("Done.");
If you want to completely hide the out functionality you must use a wrapper method. If you care only for "valid" values and the validity is well-defined by the <10 expression, then you can hide the <10 expression in that wrapper, and use a Nullable<int> in your code. That would be semantically correct.
static int counter = 0;
static void getCounterValue(out int val)
{
val = counter;
counter++;
}
static Nullable<int> getValidCounterValue()
{
int outResult;
getCounterValue(out outResult);
if (outResult < 10)
{
return null;
}
else
{
return outResult;
}
}
static void Main()
{
Nullable<int> checkVal = new Nullable<int>();
while (!checkVal.HasValue)
{
checkVal = getValidCounterValue();
Console.WriteLine("Still waiting.");
}
Console.WriteLine("Done. Valid value is:" + checkVal.Value.ToString());
}
I need help switching between while loops and resuming to the exact state that they were in.
An example would be this:
while(1==1)
{
x++;
x++;
x++;
x++;
}
while(1==1)
{
Console.WriteLine("X=" + x);
Console.WriteLine("X=" + x);
Console.WriteLine("X=" + x);
Console.WriteLine("X=" + x);
}
I am working for a project that lets you create an OS in C#. It is called Cosmos and a quick google search should land you with some info.
What I need to do is to pause one of the loops, and resume (or start) a different loop until the time is over, then that loop will be paused and a different one will be resumed and so on in an infinite cycle.
I am trying to make a simple task scheduler, and I plan to make a lot more changes than simple while loop switching, but I would like this as a primitive state and for testing.
So, what would need to happen is that one while loop executes, then is paused and the second one is executed. What would need to happen is that each loop would pause and switch to a different one, effectively seeming as if they are running at the same time. So, what would happen is that x would increase, then be printed, x increased, and so on.
Well, we could do coöperative (nonpreëmptive) multi-tasking by creating state machines to handle each loop:
private interface IStateMachine
{
void DoNext();
}
private class Loop0 : IStateMachine
{
private int _state;
private int x;
public void DoNext()
{
switch (_state)
{
case 0:
x++;
_state = 1;
break;
case 1:
x++; // This is of course the same as previous, but I'm matching
// the code in your question. There's no reason why it need
// not be something else.
_state = 2;
break;
case 2:
x++;
_state = 3;
break;
case 3:
x++;
_state = 0;
break;
}
}
}
private class Loop1 : IStateMachine
{
private int _state;
private int x;
public void DoNext()
{
switch (_state)
{
case 0:
Console.WriteLine("X=" + x);
_state = 1;
break;
case 1:
Console.WriteLine("X=" + x);
_state = 2;
break;
case 2:
Console.WriteLine("X=" + x);
_state = 3;
break;
case 3:
Console.WriteLine("X=" + x);
_state = 0;
break;
}
}
}
private static void Driver()
{
// We could have all manner of mechanisms for deciding which to call, e.g. keep calling one and
// then the other, and so on. I'm going to do a simple time-based one here:
var stateMachines = new IStateMachine[] { new Loop0(), new Loop1() };
for (int i = 0;; i = (i + 1) % stateMachines.Length)
{
var cur = stateMachines [i];
DateTime until = DateTime.UtcNow.AddMilliseconds (100);
do
{
cur.DoNext ();
} while (DateTime.UtcNow < until);
}
}
There are two big problems with this:
The x in each is a separate x. We need to box the int or wrap it in a reference type so that both methods can be accessing the same variable.
The relationship between your loops and these state machines isn't very clear.
Luckily there already exists a way (indeed more than one) to write a method in C# that is turned into a state-machine with a method for moving to the next state that handles both of these issues:
private static int x;
private static IEnumerator Loop0()
{
for(;;)
{
x++;
yield return null;
x++;
yield return null;
x++;
yield return null;
x++;
yield return null;
}
}
private static IEnumerator Loop1()
{
for(;;)
{
Console.WriteLine("X=" + x);
yield return null;
Console.WriteLine("X=" + x);
yield return null;
Console.WriteLine("X=" + x);
yield return null;
Console.WriteLine("X=" + x);
yield return null;
}
}
private static void Driver()
{
// Again, I'm going to do a simple time-based mechanism here:
var stateMachines = new IEnumerator[] { Loop0(), Loop1() };
for (int i = 0;; i = (i + 1) % stateMachines.Length)
{
var cur = stateMachines [i];
DateTime until = DateTime.UtcNow.AddMilliseconds (100);
do
{
cur.MoveNext ();
} while (DateTime.UtcNow < until);
}
}
Now not only is it easy to see how this relates to your loops (each of the two methods have the same loop, just with added yield return statements), but the sharing of x is handled for us too, so this example actually shows it increasing, rather than an unseen x incrementing and a different x that is always 0 being displayed.
We can also use the value yielded to provide information about what our coöperative "thread" wants to do. For example, returning true to always give up its time slice (equivalent to calling Thread.Yield() in C# multi-threaded code):
private static int x;
private static IEnumerator<bool> Loop0()
{
for(;;)
{
x++;
yield return false;
x++;
yield return false;
x++;
yield return false;
x++;
yield return true;
}
}
private static IEnumerator<bool> Loop1()
{
for(;;)
{
Console.WriteLine("X=" + x);
yield return false;
Console.WriteLine("X=" + x);
yield return false;
Console.WriteLine("X=" + x);
yield return false;
Console.WriteLine("X=" + x);
yield return true;
}
}
private static void Driver()
{
// The same simple time-based one mechanism, but this time each coroutine can
// request that the rest of its time-slot be abandoned.
var stateMachines = new IEnumerator<bool>[] { Loop0(), Loop1() };
for (int i = 0;; i = (i + 1) % stateMachines.Length)
{
var cur = stateMachines [i];
DateTime until = DateTime.UtcNow.AddMilliseconds (100);
do
{
cur.MoveNext ();
} while (!cur.Current && DateTime.UtcNow < until);
}
}
As I'm using a bool here I have only two states that affect how Driver() (my simple scheduler) acts. Obviously a richer datatype would allow for more options, but be more complex.
One possibility would be to have your compiler have a type of method that must return void (comparable to how yield and await have restrictions on the return types of methods that use them in C#) which could contain keywords like thread opportunity, thread yield and thread leave which would then be mapped to yield return false, yield return true and yield break in the C# above.
Of course, being coöperative it requires explicit code to say when other "threads" might have an opportunity to run, which in this case is done by the yield return. For the sort of preëmptive multi-threading that we enjoy just writing in C# for the operating systems it can run on, where time slices can end at any point rather than just where we explicitly allow it will require you to compile the source to produce such state machines, without their being instructions in that source. This is still coöperative, but forces that coöperation out of the code when compiling.
Truly preëmptive multi-threading would require that you have some way of storing the current state of each loop when switching to another thread (just as the stack of each thread in a .NET program does). In a virtual OS you could do this by building threads on top of the underlying OS's threads. In a non-virtual OS you're likely going to have to build your threading mechanism closer to the metal, with the scheduler changing the instruction pointer when threads change,
Let's say I have two sequences returning integers 1 to 5.
The first returns 1, 2 and 3 very fast, but 4 and 5 take 200ms each.
public static IEnumerable<int> FastFirst()
{
for (int i = 1; i < 6; i++)
{
if (i > 3) Thread.Sleep(200);
yield return i;
}
}
The second returns 1, 2 and 3 with a 200ms delay, but 4 and 5 are returned fast.
public static IEnumerable<int> SlowFirst()
{
for (int i = 1; i < 6; i++)
{
if (i < 4) Thread.Sleep(200);
yield return i;
}
}
Unioning both these sequences give me just numbers 1 to 5.
FastFirst().Union(SlowFirst());
I cannot guarantee which of the two methods has delays at what point, so the order of the execution cannot guarantee a solution for me. Therefore, I would like to parallelise the union, in order to minimise the (artifical) delay in my example.
A real-world scenario: I have a cache that returns some entities, and a datasource that returns all entities. I'd like to be able to return an iterator from a method that internally parallelises the request to both the cache and the datasource so that the cached results yield as fast as possible.
Note 1: I realise this is still wasting CPU cycles; I'm not asking how can I prevent the sequences from iterating over their slow elements, just how I can union them as fast as possible.
Update 1: I've tailored achitaka-san's great response to accept multiple producers, and to use ContinueWhenAll to set the BlockingCollection's CompleteAdding just the once. I just put it here since it would get lost in the lack of comments formatting. Any further feedback would be great!
public static IEnumerable<TResult> SelectAsync<TResult>(
params IEnumerable<TResult>[] producer)
{
var resultsQueue = new BlockingCollection<TResult>();
var taskList = new HashSet<Task>();
foreach (var result in producer)
{
taskList.Add(
Task.Factory.StartNew(
() =>
{
foreach (var product in result)
{
resultsQueue.Add(product);
}
}));
}
Task.Factory.ContinueWhenAll(taskList.ToArray(), x => resultsQueue.CompleteAdding());
return resultsQueue.GetConsumingEnumerable();
}
Take a look at this.
The first method just returns everything in order results come.
The second checks uniqueness. If you chain them you will get the result you want I think.
public static class Class1
{
public static IEnumerable<TResult> SelectAsync<TResult>(
IEnumerable<TResult> producer1,
IEnumerable<TResult> producer2,
int capacity)
{
var resultsQueue = new BlockingCollection<TResult>(capacity);
var producer1Done = false;
var producer2Done = false;
Task.Factory.StartNew(() =>
{
foreach (var product in producer1)
{
resultsQueue.Add(product);
}
producer1Done = true;
if (producer1Done && producer2Done) { resultsQueue.CompleteAdding(); }
});
Task.Factory.StartNew(() =>
{
foreach (var product in producer2)
{
resultsQueue.Add(product);
}
producer2Done = true;
if (producer1Done && producer2Done) { resultsQueue.CompleteAdding(); }
});
return resultsQueue.GetConsumingEnumerable();
}
public static IEnumerable<TResult> SelectAsyncUnique<TResult>(this IEnumerable<TResult> source)
{
HashSet<TResult> knownResults = new HashSet<TResult>();
foreach (TResult result in source)
{
if (knownResults.Contains(result)) {continue;}
knownResults.Add(result);
yield return result;
}
}
}
The cache would be nearly instant compared to fetching from the database, so you could read from the cache first and return those items, then read from the database and return the items except those that were found in the cache.
If you try to parallelise this, you will add a lot of complexity but get quite a small gain.
Edit:
If there is no predictable difference in the speed of the sources, you could run them in threads and use a synchronised hash set to keep track of which items you have already got, put the new items in a queue, and let the main thread read from the queue:
public static IEnumerable<TItem> GetParallel<TItem, TKey>(Func<TItem, TKey> getKey, params IEnumerable<TItem>[] sources) {
HashSet<TKey> found = new HashSet<TKey>();
List<TItem> queue = new List<TItem>();
object sync = new object();
int alive = 0;
object aliveSync = new object();
foreach (IEnumerable<TItem> source in sources) {
lock (aliveSync) {
alive++;
}
new Thread(s => {
foreach (TItem item in s as IEnumerable<TItem>) {
TKey key = getKey(item);
lock (sync) {
if (found.Add(key)) {
queue.Add(item);
}
}
}
lock (aliveSync) {
alive--;
}
}).Start(source);
}
while (true) {
lock (sync) {
if (queue.Count > 0) {
foreach (TItem item in queue) {
yield return item;
}
queue.Clear();
}
}
lock (aliveSync) {
if (alive == 0) break;
}
Thread.Sleep(100);
}
}
Test stream:
public static IEnumerable<int> SlowRandomFeed(Random rnd) {
int[] values = new int[100];
for (int i = 0; i < 100; i++) {
int pos = rnd.Next(i + 1);
values[i] = i;
int temp = values[pos];
values[pos] = values[i];
values[i] = temp;
}
foreach (int value in values) {
yield return value;
Thread.Sleep(rnd.Next(200));
}
}
Test:
Random rnd = new Random();
foreach (int item in GetParallel(n => n, SlowRandomFeed(rnd), SlowRandomFeed(rnd), SlowRandomFeed(rnd), SlowRandomFeed(rnd))) {
Console.Write("{0:0000 }", item);
}
If I step through the following code the call to ReturnOne() is skipped.
static IEnumerable<int> OneThroughFive()
{
ReturnOne();
yield return 2;
yield return 3;
yield return 4;
yield return 5;
}
static IEnumerator<int> ReturnOne()
{
yield return 1;
}
I can only assume the compiler is stripping it out because what I'm doing is not valid. I'd like the ability to isolate my enumeration into various methods. Is this possible?
You're not actually using the result of ReturnOne. You're calling the method, and ignoring the return value... which means you'd never actually see any of your code being run. You can do it like this:
static IEnumerable<int> OneThroughFive()
{
foreach (int x in ReturnOne())
{
yield x;
}
yield return 2;
yield return 3;
yield return 4;
yield return 5;
}
C# doesn't (currently at least :) have a sort of "yield all" construct.
The fact that you're not getting to step into it has nothing to do with the fact that you've got a call within an iterator block - it's just that until you start using the result of an iterator block, none of the code runs. That's why you need to separate out argument validation from yielding. For example, consider this code:
public IEnumerator<string> ReturnSubstrings(string x)
{
if (x == null)
{
throw ArgumentNullException();
}
for (int i = 0; i < x.Length; i++)
{
yield return x.Substring(i);
}
}
...
ReturnSubstring(null); // No exception thrown
You need to write it like this:
public IEnumerator<string> ReturnSubstrings(string x)
{
if (x == null)
{
throw ArgumentNullException();
}
return ReturnSubstringsImpl(x);
}
private IEnumerator<string> ReturnSubstringsImpl(string x)
{
for (int i = 0; i < x.Length; i++)
{
yield return x.Substring(i);
}
}
For more details, read chapter 6 of C# in Depth - which happens to be a free chapter in the first edition :) Grab it here.