C# // How to make few loops work in the same time? - c#

I've been programming console apps for 1 year and I think its time to start something with forms. I don't really know how to make 2 loops work at the same time.
Could any1 help me and give me an example of 2 loops, working together (1 counting from 1 to 100 and 2nd countin from 100 to 200 (both at the same time, lets say 2 message boxes)). I've been looking for smth like that on the net but without success.
I'd also like to know if infinite whiles has to be like while (5>2) or if theres a better way to do that.
Thanks in advance !

I don't really know how to make 2 loops work at the same time.
This is a simple question with an enormous answer, but I'll try to break it down for you.
The problem you're describing at its basic level is "I have two different hunks of code that both interact with the user in some way. I would like to give the user the impression that both hunks of code are running at the same time, smoothly responding to user input."
Obviously the easiest way to do that is to write two programs. That is, make the operating system solve the problem. The operating system somehow manages to have dozens of different processes running "at the same time", all interacting smoothly (we hope) with the user.
But having two processes imposes a high cost. Processes are heavyweight, and it is expensive for the two hunks of code to talk to each other. Suppose you therefore want to have the two hunks of code in the same program. Now what do you do?
One way is to put the two hunks of code each on their own thread within the same process. This seems like a good idea, but it creates a lot of problems of its own. Now you have to worry about thread safety and deadlocks and all of that. And, unfortunately, only one thread is allowed to communicate with the user. Every forms application has a "UI" thread. If you have two "worker" threads running your hunks of code, they have to use cross-thread communication to communicate with the UI thread.
Another way is to break up each hunk of code into tiny little pieces, and then schedule all the pieces to run in order, on the UI thread. The scheduler can give priority to user interaction, and any particular tiny piece of work is not going to block and make the UI thread unresponsive.
It is this last technique that I would suggest you explore. We are doing a lot of work in C# 5 to make it easier to write programs in this style.
See http://msdn.microsoft.com/en-us/async for more information about this new feature.

Not sure if this is what you mean about the two loops.
Infinite loops is anything where while (expression is true) where your expression is 5>2 is always returning true and there is no terminating out of the loop i.e. return; or break;

Drop two labels on the form in Designer view. And then add this in Code view:
public Form1()
{
InitializeComponent();
Shown += new EventHandler(Form1_Shown);
}
void Form1_Shown(object sender, EventArgs e)
{
for (int i = 1; i <= 100; i++)
{
label1.Text = i.ToString();
// "Second loop"
label2.Text = (i + 100).ToString();
Update();
System.Threading.Thread.Sleep(10);
}
}
You'll get two numbers counting simultaneously. One from 1-100. The other from 101-200.

This?
for (int i = 1; i <= 100; i++)
{
//..
for (int i2 = 100; i2 <= 200; i2++)
{
//..
}
}

Related

(C#) BackgroundWorker() ProgressChanged not working

I have a WPF application that consist of two threads simulating an enterprise producting and selling items in 52 weeks (only one transaction is allowed per week). I need to use a background worker as well so that I can display the data in a listview. As of right now, my UI freezes when clicking on simulate but I can see that the output is still working in the debugging terminal. I have tried everything that I can think of and to be honest, I have had the help of my teacher and even he couldn't find a working solution.
What is freezing my UI when I call Simulate() ?
When my code is different and my UI isn't freezing, my listview never updates because it seems that DataProgress() doesn't work — e.UserStart is never iterating.
Simulate button calls :
private void Simulate(object sender, RoutedEventArgs e)
{
// Declare BackgroundWorker
Data = new ObservableCollection<Operations>();
worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.WorkerSupportsCancellation = true;
worker.RunWorkerAsync(52);
worker.DoWork += ShowData;
worker.ProgressChanged += DataProgress;
worker.RunWorkerCompleted += DataToDB;
Production = new Production(qtyProduction, timeExecProd);
Sales = new Sales(qtySales, timeExecSales);
Thread prod = new Thread(Production.Product);
prod.Start();
Thread.Sleep(100);
Thread sales = new Thread(Sales.Sell);
sales.Start();
}
DoWork : ShowData() :
Console.WriteLine("Simulation started | Initial stock : 500");
Production = new Production(qtyProduction, timeExecProd);
Sales = new Sales(qtySales, timeExecSales);
while (Factory.Week < max) // max = 52
{
if (worker.CancellationPending) // also this isn't reacting to worker.CancelAsync();
e.Cancel = true;
// My teacher tried to call my threads from here, but it breaks the purpose of having
// two threads as he was just calling 52 times two functions back to back and therefore
// wasn't "randomizing" the transactions.
int progressPercentage = Convert.ToInt32(((double)(Factory.Week) / max) * 100);
(sender as BackgroundWorker).ReportProgress(progressPercentage, Factory.Week);
}
ProgressChanged : DataProgress() :
if (e.UserState != null) // While using debugger, it looks like this is called over & over
{
Data.Add(new Operations()
{
id = rnd.Next(1,999),
name = Factory.name,
qtyStock = Factory.Stock,
averageStock = Factory.AverageStock,
week = Factory.Week
});
listview.ItemsSource = Data;
}
RunWorkerCompleted : DataToDB() :
// Outputs "Work done" for now.
In case you want to know what happens when I call my threads, it looks like this :
Sell() :
while (Factory.Week <= 52)
{
lock (obj)
{
// some math function callings¸
Factory.Week++;
}
Thread.Sleep(timeExecSales);
}
Should I use a third thread just for updating my listview? I don't see how as I need it to be synced with my static variables. This is my first project for learning multithreading... I'm kind of clueless and flabbergasted that even my teacher can't help.
On the one hand, there isnt enough context in the code posted to get a full picture to answer your questions accurately. We can, however, deduce what is going wrong just from the code you have posted.
First, lets try to answer your two questions. We can likely infer the following:
This code here:
if (e.UserState != null)
{
Data.Add(new Operations()
{
id = rnd.Next(1,999),
name = Factory.name,
qtyStock = Factory.Stock,
averageStock = Factory.AverageStock,
week = Factory.Week
});
listview.ItemsSource = Data;
}
You are using a Windows Forms background thread object to try and update a WPF GUI object which should only be done on the main GUI thread. There is also the obvious no-no of never updating GUI objects from non-UI threads. Using BackgroundWorker also has its own issues with threading (foreground/background), contexts and execution, as it relies on the Dispatcher and SynchronizationContexts to get the job done.
Then there is the curiosity of setting the binding over and over in this line:
listview.ItemsSource = Data;
Let's put a pin in that for a moment...
There is, as the other commenter pointer out already, no exit strategy in your while loop:
while (Factory.Week < max) // max = 52
{
if (worker.CancellationPending) // also this isn't reacting to worker.CancelAsync();
e.Cancel = true;
// My teacher tried to call my threads from here, but it breaks the purpose of having
// two threads as he was just calling 52 times two functions back to back and therefore
// wasn't "randomizing" the transactions.
int progressPercentage = Convert.ToInt32(((double)(Factory.Week) / max) * 100);
(sender as BackgroundWorker).ReportProgress(progressPercentage, Factory.Week);
}
But thats not the bigger problem... in addition to the misuse/misunderstanding of when/how many/how to use threading, there doesnt seem to be any kind of thread synchronization of any kind. There is no way to predict or track thread execution of lifetime in this way.
At this point the question is technically more or less answered, but I feel like this will just leave you more frustrated and no better off than you started. So maybe a quick crash course in basic design might help straighten out this mess, something your teacher should have done.
Assuming you are pursuing software development, and since you have chosen WPF here as your "breadboard" so to speak, you will likely come across terms such as MVC (model view controller) or MVVM (model view view-model). You will also likely come across design principles such as SOLID, separation of concerns, and grouping things into services.
Your code here is a perfect example of why all of these frameworks and principles exist. Lets look at some of the problems you have encountered and how to fix them:
You have threading code (logic and services - controller [loosely speaking]) mixed in with presentation code (listview update - view) and collection update (your observable collection - model). Thats one reason (of many) you are having such a difficult time coding, fixing and maintaining the problem at hand. To clean it up, separate it out (separation of concerns). You might even move each operation into its own class with an interface/API to that class (service/ micro-service).
Not everything needs to be solved with threads. But for now, lets learn to crawl, then walk before we run. Before you start learning about async/await or the TPL (task parallel library) lets go old school. Get a good book... something even from 20 years ago is find... go old school, and learn how to use the ThreadPool and kernel synchronization objects such as mutexes, events, etc and how to signal between threads. Once you master that, then learn about TPL and async/await.
Dont cross the streams. Dont mix WinForms, WPF and I even saw Console.WriteLine.
Learn about Data Binding, and in particular how it works in WPF. ObservableCollection is your friend, bind your ItemsSource to it once, then update the ObservableCollection and leave the GUI object alone.
Hopefully this will help you straighten out the code and get things running.
Good luck!

Check mouse pointer state using callback

I need a reliable method to check the mouse pointer state, and to count how many times it has changed, e.g. from 'normal' pointer to the hourglass/circle or vice versa. It is part of a performance test that measures response times, and the only way to determine whether a certain business process has finished is by observing the mouse pointer, and to count how many times it has gone from "normal" to "busy" and back again. Once it done this twice, the process is finished. I know - it's horrible, and a rubbish workaround, but it's the only thing I can use.
I have implemented something that works, but it has one crucial weakness: if the mouse pointer changes while the thread has gone to sleep, then I "miss" this change and consequently the exit condition. I will reduce the wait time to 5 or 10 milliseconds, but it's still not a good solution.
Here's the code I have, to give you an idea of what's going on:
TimeSpan timePassed = new TimeSpan();
bool lastMousePointerState = ConvertMousePointerStateToBoolean(Mouse.CursorName);
bool currentMousePointerState = true;
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
while(pointerChanges <= 1 && timePassed.Seconds < synchDurationTimeout)
{
Thread.Sleep(100);
currentMousePointerState = ConvertMousePointerStateToBoolean(Mouse.CursorName);
var variableComparison = lastMousePointerState ^ currentMousePointerState;
if (variableComparison.Equals(true))
{
pointerChanges++;
}
timePassed = stopWatch.Elapsed;
lastMousePointerState = currentMousePointerState;
}
I had a look at this article to see if perhaps I could make use of callback functions, and what the article describes does work but only for mouse actions, not its state. Since I have practically no experience with callbacks and making calls out to the OS from .NET, I was hoping someone could tell me if a) what I have in mind is generally possible, and if so b) perhaps provide a working code snippet that would achieve what I need.
Thanks in advance !
Edit: I think the GetCursorInfo function might be what I need, but the description is so terse as to be useless to me ;-)
Despite the overwhelming number of responses here, I'd like to answer my own question :-)
What I ended up implementing (and what is good enough for my purposes) is to use the code that was provided by Atomic Object.
I simply generate the dll from the C++ code, and use a loop to check the state. It is still not as good as a callback/notification mechanism, but I need to finish this and this is the best solution to date.

Looking for a cheaper way to update controls than Update()

In a large loop I change several values and need them to be updatet. I dont want to use a BackGroundWorker.
Is there a cheaper way to make the updates, something like to tell the application to paint all pending changes?
void ExampleFunc()
{
// The original function is more complex
for (int i = 0; i < 10000; i++)
{
MyControl1.Text = NewText1(i);
MyControl2.Text = OtherNewText(i);
MyControl1.Update();
MyControl1.Update();
}
}
EDIT:
Why I do need to do it this way:
I usually use BackGroundWorker for situations like that, but in this case on some PCs I get problems with the invokes. So I can't use use it in this case
You say that you cannot use a separate thread and that you must repaint often enough to give the user feedback.
Repainting is expensive. Paint every 10th iteration or every 100ms to reduce the overhead.

Asp.net -- Multithreading in C#

I have a huge data to run which takes awful amount of time so thought Threading might do the job for me quickly.
What I do : Call SQL Stored Procedures from ASP.NET front end and processing takes place there and it takes almost 30 hours.
What I need : I have split the data into different batches and created respective SPs for each. Now I require all SPs to be running at the same time at a single button click.
Please help!
I used the below code but it doesnt seem to run in parallel.
protected void Button3_Click(object sender, EventArgs e)
{
Thread t1 = new Thread(Method1);
Thread t2 = new Thread(Method2);
t1.Start();
t2.Start();
t1.Join();
t2.Join();
}
void Method1()
{
for (int i = 0; i < 10000; i++)
{
Response.Write("hello1"+i);
Response.Write("<br>");
}
}
void Method2()
{
for (int i = 0; i < 10000; i++)
{
Response.Write("hello2" + i);
}
}
You probably don't want to be doing this directly in ASP.NET for a variety of reasons, such as the worker process has limited execution time.
Also note that the SqlConnection etc also have their own time limits.
What you should really do is queue up the work to do (using IPC or another database table etc) and have something like a Windows service or external process in a scheduled task pick up and process through the queue.
Hell, you could even kick off a job within SQL Server and have that directly do the work.
Threading doesnt magically speed up your process.
If you dont know what you are doing server side threading is not a good idea in general.
Sql server probably will time out for 30hrs :)
for 30 hours of job Asp.net is not the way to go. This is a big process and you shouldn't handle it within Asp.net. As an alternative you might want to write a windows service. Pass your parameters to it ( maybe with msmq or some kind of messaging system) Do your process and send progress to web application show it with signalR or ajax pulls.
Narendran, start here:
http://www.albahari.com/threading/
This is the best Threading tutorial I have seen online and respective book is also very good.
Make sure you spend enough time to go through the whole tutorial(I have done it and believe me, it worth it!).
As said above using Join method of thread class in this case defeats the purpose of using threads. Instead of using join use lock(see basic Synchoronization in the above tutorial) to make sure threads are synchronized.
Also as mentioned, before doing multithreading Run those stored procedures on SQL server directly and all together. If it still takes 30 hours for them to get executed ,then using Threading won't do any help. If you see less than 30 hours then you may benefeat from multithreading.

.NET EventWaitHandle slow

I'm using waveOutWrite with a callback function, and under native code everything is fast. Under .NET it is much slower, to the point I think I'm doing something very wrong, 5 or 10 times slower sometimes.
I can post both sets of code, but seems like too much, so I'll just post the C code that is fast and point out the minor variances in the .NET code.
HANDLE WaveEvent;
const int TestCount = 100;
HWAVEOUT hWaveOut[1]; // don't ask why this is an array, just test code
WAVEHDR woh[1][20];
void CALLBACK OnWaveOut(HWAVEOUT,UINT uMsg,DWORD,DWORD,DWORD)
{
if(uMsg != WOM_DONE)
return;
assert(SetEvent(WaveEvent)); // .NET code uses EventWaitHandle.Set()
}
void test(void)
{
WaveEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
assert(WaveEvent);
WAVEFORMATEX wf;
memset(&wf,0,sizeof(wf));
wf.wFormatTag = WAVE_FORMAT_PCM;
wf.nChannels = 1;
wf.nSamplesPerSec = 8000;
wf.wBitsPerSample = 16;
wf.nBlockAlign = WORD(wf.nChannels*(wf.wBitsPerSample/8));
wf.nAvgBytesPerSec = (wf.wBitsPerSample/8)*wf.nSamplesPerSec;
assert(waveOutOpen(&hWaveOut[0],WAVE_MAPPER,&wf,(DWORD)OnWaveOut,0,CALLBACK_FUNCTION) == MMSYSERR_NOERROR);
for(int x=0;x<2;x++)
{
memset(&woh[0][x],0,sizeof(woh[0][x]));
woh[0][x].dwBufferLength = PCM_BUF_LEN;
woh[0][x].lpData = (char*) malloc(woh[0][x].dwBufferLength);
assert(waveOutPrepareHeader(hWaveOut[0],&woh[0][x],sizeof(woh[0][x])) == MMSYSERR_NOERROR);
assert(waveOutWrite(hWaveOut[0],&woh[0][x],sizeof(woh[0][x])) == MMSYSERR_NOERROR);
}
int bufferIndex = 0;
DWORD times[TestCount];
for(int x=0;x<TestCount;x++)
{
DWORD t = timeGetTime();
assert(WaitForSingleObject(WaveEvent,INFINITE) == WAIT_OBJECT_0); // .NET code uses EventWaitHandle.WaitOne()
assert(woh[0][bufferIndex].dwFlags & WHDR_DONE);
assert(waveOutWrite(hWaveOut[0],&woh[0][bufferIndex],sizeof(woh[0][bufferIndex])) == MMSYSERR_NOERROR);
bufferIndex = bufferIndex == 0 ? 1 : 0;
times[x] = timeGetTime() - t;
}
}
The times[] array for the C code always has values around 80, which is the PCM buffer length I am using. The .NET code also shows similar values sometimes, however, it sometimes shows values as high as 1000, and more often values in the 300 to 500 range.
Doing the part that is in the bottom loop inside the OnWaveOut callback instead of using events, makes it fast all the time, with .NET or native code. So it appears the issue is with the wait events in .NET only, and mostly only when "other stuff" is happening on the test PC -- but not a lot of stuff, can be as simple as moving a window around, or opening a folder in my computer.
Maybe .NET events are just really bad about context switching, or .NET apps/threads in general? In the app I'm using to test my .NET code, the code just runs in the constructor of a form (easy place to add test code), not on a thread-pool thread or anything.
I also tried using the version of waveOutOpen that takes an event instead of a function callback. This is also slow in .NET but not in C, so again, it points to an issue with events and/or context switching.
I'm trying to keep my code simple and setting an event to do the work outside the callback is the best way I can do this with my overall design. Actually just using the event driven waveOut is even better, but I tried this other method because straight callbacks are fast, and I didn't expect normal event wait handles to be so slow.
Maybe not 100% related but I faced somehow the same issue: calling EventWaitHandle.Set for X times is fine, but then, after a threshold that I can't mention, each call of this method takes 1 complete second!
Is appears that some .net way to synchronize thread are much slower than the ones you use in C++.
The all mighty #jonskeet once made a post on his web site (https://jonskeet.uk/csharp/threads/waithandles.html) where he also refers the very complex concept of .net synchronization domains explained here: https://www.drdobbs.com/windows/synchronization-domains/184405771
He mentions that .net and the OS must communicate in a very very very time precise way with object that must be converted from one environment to another. All this is very time consuming.
I summarized a lot here, not to take credit for the answer but there is an explanation. There are some recommendations here (https://learn.microsoft.com/en-us/dotnet/standard/threading/overview-of-synchronization-primitives) about some ways to choose how to synchronize depending on the context, and the performance aspect is mentioned a little bit.

Categories