Parallel functions return different results in C# - c#

I have these codes in my windows form C# application:
private void button7_Click(object sender, EventArgs e)
{
ThreadStart starter = delegate { thread_func(2, 1000000); };
thread1_thread = new Thread(starter);
starter = delegate { thread_func(1000000, 2000000); };
thread2_thread = new Thread(starter);
starter = delegate { thread_func(2000000, 3000000); };
thread3_thread = new Thread(starter);
starter = delegate { thread_func(3000000, 4000000); };
thread4_thread = new Thread(starter);
thread1_thread.Start();
thread2_thread.Start();
thread3_thread.Start();
thread4_thread.Start();
}
void thread_func(decimal input1,decimal input2)
{
for (; input1 < input2; input1++)
{
threadNumbers_list.Add(input1);
if (input1 % 2 != 0)
{
if (isPrime_func(input1))
{
PrimeNumbers_decimal_list.Add(input1);
}
}
}
}
public static Boolean isPrime_func(decimal number)
{
decimal boundary = (decimal)Math.Floor(Math.Sqrt((double)number));
if (number == 1) return false;
if (number == 2) return true;
for (decimal i = 2; i <= boundary; ++i)
{
if (number % i == 0) return false;
}
return true;
}
Every time I run click that button I get different results. I have tried many things but could not figure out why this happens. Even for lower ranges it happens. Just in range of 100 numbers for example it gives the same result always.
Some time my list count reaches 283138 and sometimes 283131 and other near numbers.
Another weird this is that when I comment checking even numbers, operation takes shorter time than this mode. What's wrong?

When multiple threads access a list, that list have to be thread safe or otherwise you are going to have a lot of problems.
.NET provides some thread-safe collections like the ConcurrentQueue<T> class.
Side note: Please consider using Tasks instead of threads. Also, the .NET framework supports data parallelism via the Parallel class. Consider using such class instead.
Regarding the performance when you don't check if the number is even, I tested this locally and I got the following numbers:
It takes ~76 seconds when I don't check if the number is even.
It takes ~66 seconds when I do check if the number is even.
So this does not match your measurements. It might be caused by the way you measure. I measure with a Stopwatch like this:
//...
Stopwatch sw = Stopwatch.StartNew();
thread1_thread.Start();
thread2_thread.Start();
thread3_thread.Start();
thread4_thread.Start();
thread1_thread.Join();
thread2_thread.Join();
thread3_thread.Join();
thread4_thread.Join();
long result = sw.ElapsedMilliseconds;
//...
By the way, here is something that you can do that might save some execution time for you:
Create a normal List<T> instance for each thread inside the thread_func method so that you don't have multi-threading issues. Then after the loop finishes, you can update the master list from the local list. Only updating the master list has to be thread safe. In this case I would prefer that the master list is a normal List<T> and that you use the lock keyword to synchronize access to it because you only need to update it 4 times (the number of threads).

Related

How to execute threads every min correctly?

This question is in two parts.
I have a console application that gets info from several servers and saves this info to a DB. In order to enabel that this executes simultaniously i have used threads. I am trying to make this execution automatic every minute.
Searching stackoverflow i found that this could work:
var timer = new System.Threading.Timer((e) =>
{
var models = ServerHandler.GetServerModels();
foreach (var m in models)
{
ServerHandler.MakeThreads(m);
}
Console.WriteLine("Running...");
Console.WriteLine("Press 'X' to exit or close the window, i : " + i);
i++;
}, null, 0, TimeSpan.FromMinutes(1).Seconds);
However this is not working as anticipated, it only executes once. If i change to for example this:
TimeSpan.FromMinutes(0.5).Seconds
Or:
TimeSpan.FromSeconds(30).Seconds
Then it works.
What am I doing wrong?
Second part of this question:
When this actually works as I showed above something else happens.
The process runs continuously and after 474 threads it crashes and says that the system is out of memory.
I tried using thread sleep for this but when i do that it stops executing after it has runed once.
Including this if it might help:
public static void MakeThreads(ServerModel model)
{
Thread thread = new Thread(() => SaveServerInfo(model));
thread.Start();
//Thread.Sleep(1);
//thread.Join();
}
How can I make this work?
In your first problem using the .Seconds will only return the seconds value, but you are defining the minutes value as .5, so seconds will always be zero.
If you want to return the seconds you need to use TotalSeconds
TimeSpan.FromMinutes(0.5).TotalSeconds
and in the timespan you are using you are supposed to define the milliseconds. So you're getting a huge number of threads because its running every 30 millseconds instead of every 30000 milliseconds.
So use
TimeSpan.FromMinutes(0.5).TotalMilliseconds
or what i always find easier
(int)(1000 * 60 * 0.5) // Then you just replace the 0.5 with the number of seconds.
Basically a timer does exactly what it's supposed to do: run your code every 0.5 seconds. :) An in your case, that's a problem...
(Please check for syntax errors etc, I'm writing this in notepad)
Long solution
Your problem seems to be that you don't control your threads. Here's how I'd solve it: (This long solution shows how it more or less works)
while (true)
{
// we want to run it again in 0.5 seconds.
DateTime start = DateTime.UtcNow.AddSeconds(0.5);
Thread[] threads = new Thread[models.Count];
for (int i=0; i<models.Count; ++i)
{
threads[i] = new Thread((a) => SaveServerInfo((ServerModel)a));
threads[i].Start(models[i]);
}
for (int i=0; i<models.Count; ++i)
{
threads[i].Join();
}
DateTime current = DateTime.UtcNow;
if (current < start)
{
Thread.Sleep(start.Subtract(current));
}
}
Short solution
However, this might give you issues as well: you might spawn too many threads. This can be solved with a mechanism called thread pooling. As it turns out, there's a simple way to solve this:
static void DoStuff(string s)
{
// change to a value > 0.5 as well to ensure everything works
Thread.Sleep(TimeSpan.FromSeconds(0.1));
Console.WriteLine(s);
}
static void Handle(List<string> models)
{
while (true)
{
// we want to run it again in 0.5 seconds.
DateTime start = DateTime.UtcNow.AddSeconds(0.5);
Parallel.ForEach(models, (a) => DoStuff(a));
DateTime current = DateTime.UtcNow;
if (current < start)
{
Thread.Sleep(start.Subtract(current));
}
}
}
static void Main(string[] args)
{
List<string> models = new List<string>();
for (int i = 0; i < 10; ++i)
{
models.Add(i.ToString());
}
Handle(models);
}

Save method calls with parameters in list and execute them

I am pretty new to c# and only scratching the surface. Since my skills are rather limited, I've just reached the limit of what I can do. I would like to populate a list with methods to call (including parameters) and call these methods each second or over any other period of time.
How should I start? I heard about delegates, but I am not sure if they are what I need or if they are suitable for my purposes anyway.
Sorry if this is common-sense.
As DeeMac has already said, this doesn't seem like a thing a beginner or C# would likely need and you are best off explaining why you think you need to do this. However, to do what you were saying you could do something like this:
// Here we have the list of actions (things to be done later)
List<Action> ActionsToPerform;
// And this will store how far we are through the list
List<Action>.Enumerator ActionEnumerator;
// This will allow us to execute a new action after a certain period of time
Timer ActionTimer;
public ActionsManager()
{
ActionsToPerform = new List<Action>();
// We can describe actions in this lambda format,
// () means the action has no parameters of its own
// then we put => { //some standard c# code goes here }
// to describe the action
// CAUTION: See below
ActionsToPerform.Add(() => { Function1("Some string"); });
ActionsToPerform.Add(() => { Function2(3); });
// Here we create a timer so that every thousand miliseconds we trigger the
// Elapsed event
ActionTimer = new Timer(1000.0f);
ActionTimer.Elapsed += new ElapsedEventHandler(ActionTimer_Elapsed);
// An enumerator starts at the begining of the list and we can work through
// the list sequentially
ActionEnumerator = ActionsToPerform.GetEnumerator();
// Move to the start of the list
ActionEnumerator.MoveNext();
}
// This will be triggered when the elpased event happens in out timer
void ActionTimer_Elapsed(object sender, ElapsedEventArgs e)
{
// First we execute the current action by calling it just like a function
ActionEnumerator.Current();
// Then we move the enumerator on to the next list
bool result = ActionEnumerator.MoveNext();
// if we got false moving to the next,
// we have completed all the actions in the list
if (!result)
{
ActionTimer.Stop();
}
}
// Some dummy functions...
public void Function1(string s)
{
Console.WriteLine(s);
}
public void Function2(int x)
{
Console.WriteLine("Printing hello {0} times", x);
for (int i = 0; i < x; ++i)
{
Console.WriteLine("hello");
}
}
Caution:
Here this works as expected as we just pass in some constant values. However, things get tricky if you are not doing something so trivial. For example consider this:
for (int i = 0; i < 10; ++i)
{
ActionsToPerform.Add(() => { Function2(i); });
}
This won't print out what you expect at all, it is something to do with closures which is a very much not a beginner topic.
This is in fact the number one reason why you should seriously consider why you need to do this. As you can see, there are some sophisticated concepts here that aren't normally beginner C#...

Multithreading with textbox control [duplicate]

This question already has answers here:
Multithreading in C# with Win.Forms control
(2 answers)
Closed 9 years ago.
I'm beginner in C#. And I don't understand why next two examples are giving different results. I'm using microsoft example in msdn. In first example it displays one number in the textbox. In second example it displays all numbers from 0 to 1000 for each thread.
First example:
delegate void SetTextCallback(object text);
private void WriteString(object text)
{
if (this.textBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(WriteString);
this.BeginInvoke(d, new object[] { text });
}
else
{
for (int i = 0; i <= 1000; i++)
{
textBox1.Text = text.ToString();
}
}
}
Second example:
private void MyApp_Load(object sender, EventArgs e)
{
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
}
private void WriteString(object text)
{
for (int i = 0; i <= 1000; i++)
{
textBox1.Text = text.ToString();
}
}
And method which calls these examples
private void button1_Click(object sender, EventArgs e)
{
Thread th_1 = new Thread(WriteString);
Thread th_2 = new Thread(WriteString);
Thread th_3 = new Thread(WriteString);
Thread th_4 = new Thread(WriteString);
th_1.Priority = ThreadPriority.Highest;
th_2.Priority = ThreadPriority.BelowNormal;
th_3.Priority = ThreadPriority.Normal;
th_4.Priority = ThreadPriority.Lowest;
th_1.Start("1");
th_2.Start("2");
th_3.Start("3");
th_4.Start("4");
th_1.Join();
th_2.Join();
th_3.Join();
th_4.Join();
}
Well I analyzed in my VS. I am also new to C#. But what I could infer is the following:
Program 1:
Begin Invoke is aynschronous way of calling a method. Thus it shows only one result at the end. If you have slowly did F11 in VS and observe, not really everytime you get the result 4. But sometime you get 3 too when you do F11 and go step by step at certain places(I mean delaying), due to multi threading. You should remember that, multi threading always never behave in same manner all the time, which means suppose if an application or module in multithreading gives you one result at a time, two times, and 10 times, you cannot be sure that its the correct or optimized code. Because at client environment, due to its own behavior, it can lead to different results which may potentially be unnoticed while debugging or it wont even happen. I read it in a nice blog.
Program 2:
Since its multithreading, I could see the behavior of different threads getting invoked at different time, and as it does the job, I see the textboxes are getting updated quickly in fraction of seconds thats not possible for an human eye to notice, but final result, a single number is displayed. Also you do check for cross thread calls )When you do step into every line of code using F11, you will find this behavior and understand well ) and you order not to catch it. This makes the threads to work together in second case.
This is my inference, but I can say, pretty corny! I don't claim this with confidence, but just my observation :)
Let some great folks chime in with their views to help us :)
Cheers

troubles threads in winforms

I need to calculate sum of elements in the textbox and number of elements at the same time. So I decided to create two threads - one for length of the number, and one for sum of elements. But when I start only one thread - it works correct. But when I start the second thread - form begins to work slow or stops working at all.
I create two threads
thrd = new Thread(GetLength);
thrd.Start();
thrd1 = new Thread(SetSum);
thrd1.Start();
And these are threads' functions for calculation length of the number in textbox and for calculation sum of its elements.
private void SetSum()
{
while (true)
{
if (this.label3.InvokeRequired)
this.Invoke(new Action(() => label3.Text = this.GetSum().ToString()));
}
}
private int GetSum()
{
string n = textBox1.Text;
int sum = 0;
for (int i = 0; i < n.Length; i++)
{
try
{
sum += int.Parse(n[i].ToString());
}
catch (FormatException) { };
}
return sum;
}
private void GetLength()
{
while (true)
{
if (this.label2.InvokeRequired)
this.Invoke(new Action(() => label2.Text = " | Length = " + textBox1.Text.Length.ToString()));
}
}
Where is the problem? Synchronization?
I have found a solution - I add Thread.Sleep(1) in while loop in GetLength method
Several problems here.
The task at hand is much too small for a (full) Thread. Threads are expensive to create.
By Invoking the main action, all work is done on the Main thread. Your solution is not multi-threaded after all.
Counting is easily done as a by-product of Summing (or vice versa) so 2 threads/tasks is overkill.
The while(true) ... loop will drag your process down, consuming too much CPU time for nothing
The simple answer here is not to use any threads, just run some logic in textBox1.TextChanged.
Yes, the problem is in fact synchronization: there's too much of it.
You're spawning threads that only do Invokes, which means the UI thread is doing all the work.
This part of your code is an infinite loop without any Thread.Sleep or any other Wait. This will bring CPU to 100%. You should tie this to some event or any other activity which will trigger GetLength
private void GetLength()
{
while (true)
{
if (this.label2.InvokeRequired)
this.Invoke(new Action(() => label2.Text = " | Length = " + textBox1.Text.Length.ToString()));
}
}

lock-free calc: how to sum N double numbers that are changing by other threads?

upd: Let me rephrase my question shortly.
There are N double numbers. There are N dedicated threads each of them update own double number (_cachedProduct in the example below).
Somehow I need to have sum of these numbers and I need IndexUpdated event to be raised ASAP after any double number is changed (it would be nice if such event can be raised in 10 µs or less).
Below is how I tried to implement this task
===============================================
To calculate stock exchange index I create private double[] _cachedProduct; field. These field is written
by many threads
// called from another threads
public override void InstrumentUpdated(Instrument instrument)
{
if (!_initialized)
{
if (!Initialize())
{
return;
}
}
int instrumentId = instrument.Id;
OrderBook ob = Program.market.OrderBook(instrument);
if (ob.MedianOrAskOrBid == null)
{
_cachedProduct[instrumentId] = 0;
}
else
{
_cachedProduct[instrumentId] = ((double) ob.MedianOrAskOrBid)*_ammounts[instrumentId];
}
}
_ammounts is pre-initialized array and please ignore Initialize method and variable - they just works.
In loop I just sum all _cachedProduct and when values changes I notify others.
Task.Factory.StartNew(() =>
{
while(true)
{
if (_initialized)
{
break;
}
}
while (true)
{
CalculateAndNotify();
//Thread.Sleep(5);
}
}
, TaskCreationOptions.LongRunning);
protected void CalculateAndNotify()
{
var oldValue = Value;
Calculate();
if (oldValue != Value)
{
NotifyIndexChanged();
}
}
protected override void Calculate()
{
double result = 0;
for (int i = 0; i < _instrumentIds.Count(); i++)
{
int instrumentId = _instrumentIds[i];
if (_cachedProduct[instrumentId] == 0)
{
Value = null;
return;
}
result += _cachedProduct[instrumentId];;
}
Value = result;
}
I must use Interlocked to update my double _cachedProduct values but please ignore that fact now, what other problems with this code do you see?
Should I call Calculate method inside while(true) so I always use one core without delays. My machine has 24 cores so I was thinking this is ok.
However without Thread.Sleep(5) (commented) I do see significant slow-down in the program overall and I do not understand why. Program executes several dozens times slower in many places.
The question is if my idea of using while(true) without any locking at all is OK. Or should I introduce some locking method so I would only Calculate index when one of of _cachedProduct is updated?
I think you might get better performance and clearer code if you do not use an extra thread and loop for your sum. On every change to an instrument you calculate the difference and immediately update the index and perform the notify
So if a thread calls InstrumentUpdated for a single instrument;
change = newvalue - currentvalue;
// used interlocked here to change the index threadsafe
StockExchangeSum = Interlocked.Add(ref StockExchangeSum,change);
NotifyIndexChanged();
Can double[] be a more complex type?
How does WaitHandle.WaitAny compare performance wise?
Something like as follows.
private Index[] indicies;
public class Index
{
public WaitHandle Updated =
new EventWaitHandle(false, EventResetMode.AutoReset);
public double _value;
public double Value
{
get {return _value;}
set
{
if(_value != value)
{
_value = value;
Updated.Set();
}
}
}
}
TaskFactory.StartNew(() =>
{
while(true)
{
WaitHandle.Any(indicies.Select(i => i.Updated));
CalculateAndNotify();
}
});
Some points for you to think about
Have you tried profiling your calculation block in isolation to the rest of the code? I noticed this in your Calculate function:
for (int i = 0; i < _instrumentIds.Count(); i++)
_instrumentIds.Count() invokes an iteration over the entire collection and it is possible this is invoked for each trip around the loop. i.e. you are doing N^2/2 iterations of _instrumentIds
Is the _instrumentIdsIEnumerable being modified during this calculation operation? If so you could get all sorts of race conditions leading to incorrect answers.
Is the Task containing CalculateAndNotify called once or is it called many times (nested)? E.g. is there some operation inside CalculateAndNotify that could cause it to be triggered recursively?
If so, you might find you have several calculations performing simultaneously (using more than one thread until the pool is starved). Can you include some logging on start/end of operation and perhaps count the number of simultaneous calculations to check this?
If this is an issue you could include some logic whereby the CalculateAndNotify operation is queued up and new calculate operations cannot be executed until the previous has completed.

Categories