How to get some random numbers printing continually in the console? - c#

My problem is that when I am trying to use Unity to spawn some objects at randomized locations, for some unknown reason, the location of those spawned objects is the same location.
I tried to add Thread.Sleep() to my code and the location will be randomized.
Here is an example:
class Program
{
static void Main(string[] args)
{
var mytest = new Program();
Console.WriteLine(mytest.test());
Thread.Sleep(500);
Console.WriteLine(mytest.test());
Thread.Sleep(500);
Console.WriteLine(mytest.test());
Thread.Sleep(500);
}
public int test()
{
Random random = new Random();
int testrandom = random.Next(5, 100);
return testrandom;
}
}
I don't want to use Thread.Sleep() all the time, is there a way to get past this problem?
While using debugging, I found that without using Thread.Sleep(), the local variable testrandom will be randomly updated as testrandom = 30,testrandom=32,testrandom=13..., but the result is different, the result is testrandom=30 and repeats itself 3 times. Can someone tell me why is this happening? Maybe it runs too fast?

.NET Random class is seeded by system clock if no explicit seed is given, so if you create new instances in short time apart from each other each instance will give you same number. This is also reason why adding sleep between calls to mytest.test() mitigates problem, as system clock has advanced by the time Thread.Sleep is over.
You should reuse same instance of Random, and use that instance every time:
class Program
{
private Random random = new Random();
static void Main(string[] args)
{
var mytest = new Program();
Console.WriteLine(mytest.test());
Console.WriteLine(mytest.test());
Console.WriteLine(mytest.test());
}
public int test()
{
int testrandom = random.Next(5, 100);
return testrandom;
}
}
Also, you can declare your test() method and Random instance as static, so you don't have to create instance of Program-class:
class Program
{
private static Random random = new Random();
static void Main(string[] args)
{
Console.WriteLine(test());
Console.WriteLine(test());
Console.WriteLine(test());
}
public static int test()
{
int testrandom = random.Next(5, 100);
return testrandom;
}
}

Related

Thread in static constructor not work instantly

I have a static Thread which is responsible for get and update the token from remote api. I want to start that thread in a static constructor like below
using System;
using System.Threading;
namespace StaticConstructor
{
public class CallBack
{
static string _token = "init";
static Thread _threadUpdateToken;
static CallBack()
{
_threadUpdateToken = new Thread(()=>
{
int i = 0;
while (i < 3)
{
GetTokenFromAPI();
Thread.Sleep(1 * 1000);
i++;
}
});
_threadUpdateToken.Start();
Console.WriteLine($"After thread start {DateTime.Now.ToString("hh:mm:ss")}");
Thread.Sleep(10 * 1000);
Console.WriteLine($"Static constructor keep running at {DateTime.Now.ToString("hh:mm:ss")}");
Console.WriteLine($"token = {_token}");
}
public static void GetTokenFromAPI()
{
//this is for demo purpose
var rd = new Random();
_token = rd.Next().ToString();
Console.WriteLine($"token has been updated as {_token} at {DateTime.Now.ToString("hh:mm:ss")}");
}
}
class Program
{
static void Main(string[] args)
{
CallBack cb = new CallBack();
Console.ReadKey();
}
}
}
The output is
After _threadUpdateToken.Start 05:16:15
Static constructor keeps running at 05:16:25
token = init
token has been updated as 1671358759 at 05:16:25
token has been updated as 437230378 at 05:16:26
token has been updated as 1350585644 at 05:16:27
Then my question is:
1. Why thread _threadUpdateToken not start before static Constructor finished? Is that because static Constructor must be finished before any other threads access static variables?
2. What should i do if i dont want to invoke GetTokenFromAPI() directly in static Constructor like
static CallBack()
{
GetTokenFromAPI();
}
From the C# docs:
A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced.
So what is happening here is that your thread will run right up to the point it tries to call the GetTokenFromAPI static method, wait until the static constructor ends and then carry on.

C#: Initialize Random() only once in a singleton pattern

I am trying to initialize only once a random variable, let's say 'rnd'. So If from many points of my program it is called, then the random variable will not be initialized again, only first time.
So I have created a singleton but I do not know how to call only once Random().
public sealed class Randomize
{
private static Randomize instance = null;
private static readonly object padlock = new object();
Randomize()
{
}
public static Randomize Instance
{
get
{
lock (padlock)
{
if (instance == null)
{
instance = new Randomize();
}
return instance;
}
}
}
}
Within this class I would like to create a private readonly random variable, 'rnd', which is initialized only once, the first time, to:
Random rnd = new Random()
Then, I would like to create a property to read its value, for example:
public Random Rnd
{
get { return rnd; }
}
I do not want to allow to change its value because it is assigned first time only, so I only want the property to be readonly (get), not set.
So from many points of my program I can do:
private readonly Random rnd;
Random rnd = Randomize.Instance.Rnd;
But each time I call it using above expression I do not want to initizalize random variable again (by doing new Random()) instead I want to always obtain the same value it was rnd variable was initialized for first time.
Any ideas on how to do it?
Just use a static constructor, by definition that is gaurenteed to only be called once
The MSDN Documentation States :
A static constructor is used to initialize any static data, or to perform a particular action that needs to be performed once only. It is called automatically before the first instance is created or any static members are referenced.
public sealed class Randomize
{
private static Randomize instance = null;
private static readonly object padlock = new object();
public Random GetRandom { get { return rnd; } }
private static readonly Random rnd;
static Randomize()
{
rnd = new Random();
}
}
You can access Randomize.Random with the following snippet and it will always return the once-initialized Random rnd field.
public sealed class Randomize {
private static readonly Random rnd = new Random();
public static Random Random {
get {
return rnd;
}
}
}
Read only variables can be assigned in the constructor, so I would go that route.
public sealed class Randomize {
/* access level here */ Random rnd { get { return r; } }
private readonly Random r;
static Randomize() {
r = new Random();
}
}
// or
private readonly Random r = new Random();
public Random rnd {
get {
return r;
}
}

New to C# and OOP can someone explain this scope issue to me?

I haven't done much work with lists and OOP programming before so I am sorry if this is a simple formatting or visibility issue.
This is a method which is currently defined at the very top of my code
namespace CrazyMaths
{
class Program
{
static int getMemory()
{
Console.WriteLine("Please enter a number");
int locationChoice = int.Parse(Console.ReadLine());
int result = storeValues[locationChoice];
return result;
}
This is part of a separate method which calls getMemory()
else if (tempNumber == "M")
{
result = getMemory();
test = true;
}
And this is the main block of code in which I declare my list.
static void Main(string[] args)
{
List<int> storeValues = new List<int>();
The name 'storeValues' does not exist in the current context.
You should call your method like below passing the storeValues list to the function getMemory(). Else it's obviously not accessible since storeValues is defined within main() method and so it's scope is bounded within the main() method only.
getMemory(storeValues)
So your main() should look like
static void Main(string[] args)
{
List<int> storeValues = new List<int>();
getMemory(storeValues);
You should declare storeValues outside the Main function like this:
namespace CrazyMaths
{
class Program
{
private List<int> storeValues;
static int getMemory()
{
Console.WriteLine("Please enter a number");
int locationChoice = int.Parse(Console.ReadLine());
int result = storeValues[locationChoice];
return result;
}
static void Main(string[] args)
{
storeValues = new List<int>();
}

use multithread to write into text files using C#

Hope you can help me with this one.i am beginner in multithreading programming with C#.
I am trying to build a program to write all numbers from range 1 to 2000 in two text files using two threads.
Every thread should write number from 1 to 2000 that not found at any of the two files "there is no duplicated numbers in the files" and every thread should't write the number that have been wrote by the another thread.
At the end if we merged the numbers of the two files we should have the numbers from 1 to 2000
Here is the source code i am trying but there is a problem in the writing for loop in the below image
i can't handle the process of writing by the two synchronized threads and i had exception:
Object synchronization method was called from an unsynchronized block of code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
namespace Multithreading
{
class Program
{
static TextWriter file2 = new StreamWriter("file2 location");
static TextWriter file1 = new StreamWriter("file1 location");
static void Main(string[] args)
{
try
{
int[] array = new int[2000];
Thread thread1 = new Thread(Program.writeinfile1);
Thread thread2 = new Thread(Program.writeinfile2);
for (int counter = 1; counter <= 2000; counter++)
{
thread1.Start(counter);
thread2.Start(++counter);
Monitor.Enter(thread1);
Monitor.Wait(thread1);
Monitor.PulseAll(thread2);
}
}
catch (FileNotFoundException)
{
Console.WriteLine("the file you are trying to open is not found");
}
}
public static void writeinfile1(object x)
{
int converttointx = (int)x;
file1.WriteLine(converttointx);
file1.Close();
}
public static void writeinfile2(object y)
{
int converttointy = (int)y;
file2.WriteLine(converttointy);
file2.Close();
}
}
}
Here's an example of multi-threaded calls talking to one another to ensure they don't duplicate work.
I've not done exactly what you've asked for, since this looks quite homeworky; but hopefully this will help you to figure out the solution to your issue...
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace StackOverflow
{
class Program
{
static void Main(string[] args)
{
new Program();
Console.WriteLine("done");
Console.ReadKey();
}
Program()
{
int noThreads = 5;
int target = 2000;
StartThread(noThreads, target);
}
//kicks off our threads / waits for all threads to complete before returning
void StartThread(int noThreads, int target)
{
int id = noThreads--;
if (id > 0)
{
Doer doer = new Doer(id, target);
Thread t = new Thread(doer.Do);
t.Start();
StartThread(noThreads,target);
t.Join();
}
}
}
class Doer
{
static int marker = 0;
static readonly object syncLocker = new object();
readonly int id;
readonly int target;
public Doer(int id, int target)
{
this.id = id;
this.target = target;
}
public void Do()
{
while (marker < this.target)
{
int i;
lock (syncLocker)
{
i = ++marker;
}
System.Console.WriteLine("{0:00}: {1:###0}", id, i);
//Thread.Sleep(RandomNo()); //uncomment this & code below if your threads are taking turns / behaving too predictably
}
}
/*
static readonly Random rnd = new Random();
static readonly object rndSyncLocker = new object();
public static int RandomNo()
{
lock (rndSyncLocker)
{
return rnd.Next(0, 1000);
}
}
*/
}
}
You are not using the Monitor class correctly. The call to Monitor.PulseAll(thread2); should be called within thread the thread which owns the lock, which in this case would be within the writeinfile1 and writeinfile2 method.
This is why you are getting the exception:
Object synchronization method was called from an unsynchronized block of code.
See the following StackOverflow question for the correct way to use Monitor.PulseAll(object):
Help needed in Monitor.PulseAll()

c# newb question from "Head Start C# Greyhound Lab"

i'm new at C # and i'm creating a racetrack simulator, but i'm currently encountering some issues when i run my code. I have an array of four Greyhound objects, and if I call Greyhound.Run on my form1.cs and i don't have a "MessageBox.Show("Distance" + distance)" on my Run method, which shows me how many pixels each greyhound is supposed to move, all of the greyhounds end up moving the same distance. I don't understand why this is happening
namespace Race
{
class Greyhound
{
public int StartingPosition;
public int RacetrackLength;
public PictureBox MyPictureBox = null;
public int Location = 0;
public Random Randomizer;
public bool Run()
{
Point p = MyPictureBox.Location;
if (p.X + MyPictureBox.Width >= RacetrackLength)
{
//TakeStartingPostion();
return true;
}
else
{
Randomizer = new Random();
int distance = Randomizer.Next(100);
MessageBox.Show("Distance is " + distance);
p.X += distance;
MyPictureBox.Location = p;
return false;
}
}
public void TakeStartingPostion()
{
Point P = MyPictureBox.Location;
P.X = StartingPosition;
MyPictureBox.Location = P;
}
}
}
namespace Race
{
public partial class Form1 : Form
{
Guy[] guys = new Guy[3];
Greyhound[] hounds = new Greyhound[4];
public Form1()
{
InitializeComponent();
hounds[0] = new Greyhound()
{
StartingPosition = 12,
MyPictureBox = GreyHound1,
RacetrackLength = 636
};
hounds[1] = new Greyhound()
{
StartingPosition = 12,
MyPictureBox = GreyHound2,
RacetrackLength = 636
};
hounds[2] = new Greyhound()
{
StartingPosition = 12,
MyPictureBox = GreyHound3,
RacetrackLength = 636
};
hounds[3] = new Greyhound()
{
StartingPosition = 12,
MyPictureBox = GreyHound4,
RacetrackLength = 636
};
}
private void button2_Click(object sender, EventArgs e)
{
for (int i = 0; i < hounds.Length; i++)
{
hounds[i].Run();
}
}
}
}
It's because you're calling new Random() each time the Run() method hits the else block. The default Random constructor initializes the pseudorandom number generator based on the current time. When there's no interruption, all 4 method run at "the same time", so they spit out the same random numbers. To fix this, either create only a single Random, or else use a different seed for each one (by using the Random constructor that takes a seed as a parameter.)
Something like this would work:
public class Greyhound
{
public static Random randomizer = new Random();
// ... In the run method ...
int distance = Greyhound.randomizer.Next(100);
}
Update: As Groo points out, if you were actually calling Next() from multiple threads, the code I've shown isn't thread-safe. While that's not the case with your code, it's a good idea to be aware of issues like this earlier rather than later. The general solution to this (potential) problem is to surround the call to Next() with a lock, like so:
// ... After the declaration of randomizer ...
private static object randomLock = new object();
// ... New Next() call...
lock (randomLock)
Greyhound.randomizer.Next(100);
Since you probably call the Run methods of all of your objects quickly in succession, each instance of the Random class gets instantiated with the same seed, returning the same pseudo-random number.
You can solve this problem by creating a static random class which will have a single (Singleton) Random instance, making sure that each of your callers gets the next number in succession.
With some locking for thread safety, it would look something like:
public class StaticRandom
{
private static readonly Random _r = new Random();
private static object _lock = new object();
public static int Next(int max)
{
lock (_lock)
return _r.Next(max);
}
}
And then use it without instantiating it:
// no need for the "Randomizer" field anymore
int distance = StaticRandom.Next(100);
Jon Skeet has the full implementation in his miscutil library, along with some usage info.

Categories