I have a while loop with a stopper:
public Myloop()
{
bool execute == true;
While (execute == true)
{
// do some stuff
if (condidtion)
{
execute == false;
}
}
}
and I'm calling in from another function after it stops:
Myloop.execute = true;
Will this be enough to restart the loop? if not, how can I restart it from another function easy way?
No, Once a while loop is done it wont start again until you run the Myloop() function again:
public void RunLoopTwice(){
MyLoop();
MyLoop();
}
public void Myloop()
{
bool execute = true;
while (execute == true)
{
// do some stuff
if (condition)
{
execute = false;
}
}
}
Also normally code is executed in a synchronous order, so only 1 piece of code is executed at the time. with async/await, Task or Thread you can make multiple pieces of code run at once. If you are using any of this, you need to make sure you properly lock pieces of code to not get any race conditions.
You are confusing == and = operators, == is for comparison while = is for assignment. Read about C# Operators.
public void Myloop()
{
bool execute = true;
while (execute == true)
{
// do some stuff
if (condition)
{
execute = false;
}
}
}
Simpler way to do this is using break since you are not returning the value of execute field. Once the condition is met, while loop will terminate.
while (true)
{
// do some stuff
if (condition) break;
}
And you call the method using Myloop(); not Myloop.execute = true;.
You can do with two flags but this code will be run on the different thread because this code will go in the infinite loop.
For Ex.
public bool doLoop = true;
public bool doProcess = true;
public void MyLoop()
{
while(doLoop)
{
while(doProcess)
{
// do some stuff
if (condition)
{
doProcess = false;
}
}
}
}
After your need is completed than make doLoop false
Related
I've a queue of commands. One thread is trying to execute those commands.
Other threads can ask to pause the execution(and they will be blocked until the current command execution is done), and resume them.
When the thread wants to execute thoses commands(at regular interval) it flags that it want to execute commands(and is blocked until all "pause" are removed.
The only issue is that some of thoses commands might try to pause the command execution(because of some event that listen some other event, ...).
The way it has been handled until now is to store the ThreadId of the thread executing the commands, and ignore the pause request if it comes from this thread.
(You don't have to tell me it's a shity design, I know, but I've to do with it :( ).
One class is containing all this CommandQueue logic:
public void PauseDataCommandProcessing()
{
if (Thread.CurrentThread.ManagedThreadId == m_processDataCommandThreadId)
{
return;
}
lock (m_pauseLock)
{
m_pauseCounter++;
if (m_dataCommandInProgress)
{
Monitor.Wait(m_pauseLock);
}
}
}
public void ResumeDataCommandProcessing()
{
if (Thread.CurrentThread.ManagedThreadId == m_processDataCommandThreadId)
{
return;
}
lock (m_pauseLock)
{
m_pauseCounter--;
if (m_pauseCounter == 0)
{
Monitor.PulseAll(m_pauseLock);
}
}
}
//Thoses methods are called by the command executers
public void FlagCommandsExecutionInProgress()
{
m_processDataCommandThreadId = Thread.CurrentThread.ManagedThreadId;
lock (m_pauseLock)
{
while (m_pauseCounter > 0)
{
Monitor.Wait(m_pauseLock);
}
m_dataCommandInProgress = true;
}
}
public void FlagCommandsExecutionFinished()
{
lock (m_pauseLock)
{
m_dataCommandInProgress = false;
Monitor.PulseAll(m_pauseLock);
}
}
Here is how I execute them basically
CommandContainer.FlagCommandsExecutionInProgress();
try{
IEnumerable<CommandInfo> commandSet =CommandContainer.RetrieveCommands();//Get the current commands list
foreach (CommandInfo command in commandSet){
command.Execute();
}
}finally{
CommandContainer.FlagCommandsExecutionFinished();
}
In order to increase the speed of execution of thoses commands I wanted to regroup the command by "Target"(each command is applied to a specific object), and then execute in parallel each group of commands.
The idea was to execute them like this:
CommandContainer.FlagCommandsExecutionInProgress();
try{
IEnumerable<IGrouping<object, CommandInfo>> groupedCommandSet =CommandContainer.RetrieveCommands().GroupBy(c=>c.Target);//Get the current commands list
Parallel.ForEach(groupedCommandSet,commandSet=>{
foreach (CommandInfo command in commandSet){
command.Execute();
}
} );
}finally{
CommandContainer.FlagCommandsExecutionFinished();
}
But unfortunately, they will have a different ThreadId and I get some deadlocks, because they wait on themselfs to finish.
Assuming that I cannot change the way those pause are asked, do you see any way to solve my issue?
I ended by doing this: I don't know if there is a better solution, but it seems to work:
private HashSet<int> m_processDataCommandThreadIds = new HashSet<int>();
public void PauseDataCommandProcessing()
{
if (m_processDataCommandThreadIds.Contains(Thread.CurrentThread.ManagedThreadId))
{
return;
}
lock (m_pauseLock)
{
m_pauseCounter++;
if (m_dataCommandInProgress)
{
Monitor.Wait(m_pauseLock);
}
}
}
public void ResumeDataCommandProcessing()
{
if (m_processDataCommandThreadIds.Contains(Thread.CurrentThread.ManagedThreadId))
{
return;
}
lock (m_pauseLock)
{
m_pauseCounter--;
if (m_pauseCounter == 0)
{
Monitor.PulseAll(m_pauseLock);
}
}
}
//Thoses methods are called by the command executers
public void FlagCommandsExecutionInProgress()
{
m_processDataCommandThreadIds.Add(Thread.CurrentThread.ManagedThreadId);
lock (m_pauseLock)
{
while (m_pauseCounter > 0)
{
Monitor.Wait(m_pauseLock);
}
m_dataCommandInProgress = true;
}
}
public void FlagCommandsExecutionFinished()
{
m_processDataCommandThreadIds.Remove(Thread.CurrentThread.ManagedThreadId);
lock (m_pauseLock)
{
m_dataCommandInProgress = false;
Monitor.PulseAll(m_pauseLock);
}
}
public class Example {
private boolean jobInProgress = false;
public void job() {
lock(this) {
if (jobInProgress) {
return;
}
jobInProgress = true;
}
// Code to execute job goes here
// ...
}
void jobCompleted() {
lock(this) {
jobInProgress = false;
}
}
}
I got this piece of code from Wikipedia and i have one thing i am not sure of.
Why jobInProgress = true; is not set inside the locked block just after the return statement? To be more explicit i will try to give a scenario:
One thread gets the lock while others are waiting
It releases the lock but before executing jobInProgress = true;, one of the waiting threads gets the lock and tests the condition which is still false.
Is this a feasible scenario or am i not getting the flow of execution right?
You are confusing yourself:
lock(this) {
if (jobInProgress) {
return;
} // <= closing brace of if
// INSIDE LOCK, OUTSIDE IF
jobInProgress = true;
} // <= closing brace of lock
I'll note that on the wiki:
public void job() {
synchronized(this) {
if (jobInProgress) {
return;
}
// INSIDE LOCK, OUTSIDE IF
jobInProgress = true;
}
// Code to execute job goes here
// ...
}
it is exactly the same!
I have code like this:
public void Method()
{
if(something)
{
// Some code
if(something2)
{
// Now I should break from ifs and go to the code outside ifs
}
return;
}
// The code I want to go if the second if is true
}
Is there a possibility to go to that code after ifs without using any go to statement or extracting rest of the code to the other method?
Yes, I know Else ;)
But this code is farly long and should be run IF the first IF is false and when the first IF is true and the second is false.
So extracting a method I think is the best idea.
To answer your question:
public void Method()
{
do
{
if (something)
{
// some code
if (something2)
{
break;
}
return;
}
break;
}
while( false );
// The code I want to go if the second `if` is true
}
You can use a goto to drop past some code. In the example, if thing1 is true then the check for things2 is bypassed.
if (something) {
do_stuff();
if (thing1) {
do_thing1();
goto SkipToEnd;
}
if (thing2) {
do_thing2();
}
SkipToEnd:
do_thing3();
}
This is a variation of something I learned several years back. Apparently, this is popular with C++ developers.
First off, I think I know why you want to break out of IF blocks. For me, I don't like a bunch of nested blocks because 1) it makes the code look messy and 2) it can be a PITA to maintain if you have to move logic around.
Consider a do/while loop instead:
public void Method()
{
bool something = true, something2 = false;
do
{
if (!something)
break;
if (something2)
break;
} while (false);
}
The do/while loop is guaranteed to run only once just like an IF block thanks to the hardcoded false condition. When you want to exit early, just break.
public void Method()
{
if(something)
{
// Some code
if(something2)
{
// Now I should break from ifs and go to the code outside ifs
goto done;
}
return;
}
// The code I want to go if the second if is true
done: // etc.
}
Same question
Long answer
Another way starting from C# 7.0 would be using local functions. You could name the local function with a meaningful name, and call it directly before declaring it (for clarity). Here is your example rewritten:
public void Method()
{
// Some code here
bool something = true, something2 = true;
DoSomething();
void DoSomething()
{
if (something)
{
// Some code
if (something2)
{
// Now I should break from ifs and go to the code outside ifs
return;
}
return;
}
}
// The code I want to go if the second if is true
// More code here
}
public void Method()
{
if(something)
{
// Some code
if(!something2)
{
return;
}
}
// The code I want to go if the second if is true
}
In this case, insert a single else:
public void Method()
{
if(something)
{
// Some code
if(something2)
{
// Now I should break from ifs and go to the code outside ifs
}
else
return;
}
// The code I want to go if the second if is true
}
Generally: There is no break in an if/else sequence, simply arrange your code correctly in if / if else / else clauses.
public void Method()
{
if(something)
{
// Some code
if(something2)
{
// The code I want to go if the second if is true
}
return;
}
}
You can return only if !something2 or use else return:
public void Method()
{
if(something)
{
//some code
if(something2)
{
//now I should break from ifs and go to the code outside ifs
}
if(!something2) // or else
return;
}
// The code I want to go if the second if is true
}
In your code example, you should simply run the code after the ifs inside the second if instead (or set a flag like someone else mentioned, depending on the context). Use method calls to improve readability and reduce nesting.
As for actually escaping ifs, I think there is a way that conforms much more to C# standards than the answers I've seen here. Simply extract the contents of the if statement to a separate method. This also increases readability. So:
public void Method()
{
if(something)
{
//some code
if (somethingelse)
{
//break if
}
//some other code running if the above if didn't trigger
}
}
This can be accomplished as such:
public void Method()
{
if(something)
{
DoSomething();
}
}
public void DoSomething()
{
//some code
if (somethingelse)
{
return;
}
//some other code running if the above if didn't trigger
}
You can also use a lambda
if (new Func<bool>(() =>
{
if (something1)
{
// Some code that calculates "something2"
if (something2)
{
// Now I should break from ifs and go to the code outside ifs
return true;
}
}
return false;
})())
{
// The code I want to go if the second if is true
}
P.S. I think I know why people would want this. "Run stuff if all conditions are true, otherwise run other stuff". And the conditions are too complicated to put into one if or they depend one on another.
Try adding a control variable:
public void Method()
{
bool doSomethingElse = true;
if(something)
{
// Some code
if(!something2)
{
doSomethingElse = false;
}
}
if(doSomethingElse)
{
// The code I want to go if the second if is true
}
}
Another variant that may be really useful in more complicated cases:
try {
if (something)
{
// Some code
if (something2)
{
throw new Exception("Weird-01.");
// Now you will go to the catch statement
}
if (something3)
{
throw new Exception("Weird-02.");
// Now you will go to the catch statement
}
// Some code
return;
}
}
catch (Exception ex)
{
Console.WriteLine(ex); // You will get your Weird-01 or Weird-02 here
}
// The code I want to go if the second or third if is true
if (contREsponse == "yes")
{
cont = true;
}
else if (contREsponse == "no")
{
Console.WriteLine("Come back, when you change your mind.");
//exit environment:
Environment.Exit(0);
}
There is this class unit that has a property bool status that marks whether a method, request, should be called on the unit. I have my other class, and in it, there is a method that should call request. To avoid blocking the main thread, I want to call the method asynchronously. The problem is that there isn't an event for the status change, and I don't want to make my asynchronous call do ugly stuff like:
while(!status){}unit.request(args);
or
while(!status){Thread.Sleep(100)}unit.request(args);
especially when I do not know the timescale in which status turns true.
How do I do this?
update: i forgot to mention that i cannot change unit. sorry for that.
You want to call a function (be it asynchronously or not) when a property changes. You have two choices:
Attach to an even that is signalled when the property changes
Periodically check the value of the property
You can't do the first, so you must do the second.
This is a sample of how you can manage this using an event.
Suppose this is your class
public class Unit
{
private readonly object _syncRoot = new object();
private bool _status;
public event EventHandler OnChanged;
public bool Status
{
get
{
lock (_syncRoot)
{
return _status;
}
}
set
{
lock (_syncRoot)
{
_status = value;
if (_status && OnChanged != null)
{
OnChanged.Invoke(this, null);
}
}
}
}
public void Process()
{
Thread.Sleep(1000);
Status = true;
}
}
Here is how you can use it
class Program
{
static void Main(string[] args)
{
var unit = new Unit();
unit.OnChanged += Unit_OnChanged;
Console.WriteLine("Before");
Task.Factory.StartNew(unit.Process);
Console.WriteLine("After");
Console.WriteLine("Manual blocking, or else app dies");
Console.ReadLine();
}
static void Unit_OnChanged(object sender, EventArgs e)
{
//Do your processing here
Console.WriteLine("Unit_OnChanged before");
Task.Factory.StartNew(()=>
{
Thread.Sleep(1000);
Console.WriteLine("Unit_OnChanged finished");
});
Console.WriteLine("Unit_OnChanged after");
}
}
This outputs
Before
After
Manual blocking, or else app dies
Unit_OnChanged before
Unit_OnChanged after
Unit_OnChanged finished
This is the classic polling problem, and there really isn't an elegant solution when polling is concerned. But we can work some functional programming in to get something which isn't a nightmare to use.
public static CancellationTokenSource Poll(
Func<bool> termination,
Action<CancellationToken> onexit,
int waitTime = 0,
int pollInterval = 1000)
{
var cts = new CancellationTokenSource();
var token = cts.Token;
Action dispose = cts.Cancel;
var timer = new Timer(_ =>
{
if (termination() || token.IsCancellationRequested)
{
onexit(token);
dispose();
}
}, null, waitTime, pollInterval);
dispose = timer.Dispose;
return cts;
}
Example:
var condition = false;
Poll(() => condition == true, ct => Console.WriteLine("Done!"));
Console.ReadLine();
condition = true;
Console.ReadLine();
Use a System.Threading.AutoResetEvent instead of a bool if possible:
AutoResetEvent status = new AutoResetEvent();
In your asynchronous method, wait for it:
status.WaitOne();
unit.request(args);
Then, to signal it in your other class, call Set:
status.Set();
I would like to run code alternatively, so I could stop execution at any moment. Is this code safe?
static class Program
{
static void Main()
{
var foo = new Foo();
//wait for interaction (this will be GUI app, so eg. btnNext_click)
foo.Continue();
//wait again etc.
foo.Continue();
foo.Continue();
foo.Continue();
foo.Continue();
foo.Continue();
}
}
class Foo
{
public Foo()
{
new Thread(Run).Start();
}
private void Run()
{
Break();
OnRun();
}
protected virtual void OnRun()
{
for (var i = 0; i < 5; i++)
{
Console.WriteLine(i);
Break();
}
//do something else and break;
}
private void Break()
{
lock (this)
{
Monitor.Pulse(this);
Monitor.Wait(this);
}
}
public void Continue()
{
lock (this)
{
Monitor.Pulse(this);
Monitor.Wait(this);
}
}
}
Of course I know, that now the application will never ends, but that's not the point.
I need this, because I would like to present steps in some kind of an algorithm and describe what is going on in particular moment, and making everything in one thread would lead to many complications even when using small amount of loops in the code. For example those lines:
for (var i = 0; i < 5; i++)
{
Console.WriteLine(i);
Break();
}
should be then replaced with:
if (this.i < 5)
{
Console.WriteLine(i++);
}
And that is just a small example of what I want to present. The code will be more complicated than a dummy for loop.
I recommend you check out this blog post about implementing fibers.
Code (In case the site goes down.)
public class Fiber
{
private readonly Stack<IEnumerator> stackFrame = new Stack<IEnumerator>();
private IEnumerator currentRoutine;
public Fiber(IEnumerator entryPoint)
{
this.currentRoutine = entryPoint;
}
public bool Step()
{
if (currentRoutine.MoveNext())
{
var subRoutine = currentRoutine.Current
as IEnumerator;
if (subRoutine != null)
{
stackFrame.Push(currentRoutine);
currentRoutine = subRoutine;
}
}
else if (stackFrame.Count > 0)
{
currentRoutine = stackFrame.Pop();
}
else
{
OnFiberTerminated(
new FiberTerminatedEventArgs(
currentRoutine.Current
)
);
return false;
}
return true;
}
public event EventHandler<FiberTerminatedEventArgs> FiberTerminated;
private void OnFiberTerminated(FiberTerminatedEventArgs e)
{
var handler = FiberTerminated;
if (handler != null)
{
handler(this, e);
}
}
}
public class FiberTerminatedEventArgs : EventArgs
{
private readonly object result;
public FiberTerminatedEventArgs(object result)
{
this.result = result;
}
public object Result
{
get { return this.result; }
}
}
class FiberTest
{
private static IEnumerator Recurse(int n)
{
Console.WriteLine(n);
yield return n;
if (n > 0)
{
yield return Recurse(n - 1);
}
}
static void Main(string[] args)
{
var fiber = new Fiber(Recurse(5));
while (fiber.Step()) ;
}
}
"...this will be GUI app..."
Then you probably do not want and will not have sequential code like above in Main().
I.e. the main GUI thread will not execute a serial code like above, but generally be idle, repainting, etc. or handling the Continue button click.
In that event handler you may better use an Auto|ManualResetEvent to signal the worker to proceed.
In the worker, just wait for the event.
I would suggest that any time one considers using Monitor.Wait(), one should write code so that it would work correctly if the Wait sometimes spontaneously acted as though it received a pulse. Typically, this means one should use the pattern:
lock(monitorObj)
{
while(notYetReady)
Monitor.Wait(monitorObj);
}
For your scenario, I'd suggest doing something like:
lock(monitorObj)
{
turn = [[identifier for this "thread"]];
Monitor.PulseAll(monitorObj);
while(turn != [[identifier for this "thread"]])
Monitor.Wait(monitorObj);
}
It is not possible for turn to change between its being checked whether it's the current thread's turn to proceed and the Monitor.Wait. Thus, if the Wait isn't skipped, the PulseAll is guaranteed to awaken it. Note that the code would work just fine if Wait spontaneously acted as though it received a pulse--it would simply spin around, observe turn wasn't set for the current thread, and go back to waiting.