How terminate a method when an event fired - c#

I have a Validation method and a validation counter, I fire an event when the count of errors is equal to a number. How do I terminate the validation process? Maybe I should use Observer pattern?
class ValidationClass
{
private int errorsCount;
private delegate void CompleteHandler();
private event CompleteHandler ValidationComplete;
public int ErrorsCount
{
set
{
errorsCount = value;
if (errorsCount == 20)
{
ValidationComplete();
}
}
get { return errorsCount; }
}
public void ValidationClass()//constructor
{
ValidationComplete += ExcelHelpers_Complete;
}
void Validation_Complete() //
{
//terminate Validate() and return false; how?
}
public bool Validate()
{
for(...){
ErrorsCount++;
for(...){
....
ErrorsCount++;
}
....
//others conditions that increment ErrorsCount
}
}

Have your subscriber check the number of error count and do nothing if its past your maximum range. If your subscriber does not have access to the publisher object than pass the count inside the event itself. Your subscriber could also unsubscribe once this condition has been met.

Move the following code into your Validate() method:
if (errorsCount == 20)
{
ValidationComplete();
}
Now use break statement to abort your loop when the condition is true and raise ValidationComplete() event thereafter.
Your property will look like this:
public int ErrorsCount
{
set { errorsCount = value; }
get { return errorsCount; }
}
and Validate() method would look like this:
public bool Validate()
{
for(...){
ErrorsCount++;
if(Check20()) break;
for(...){
....
ErrorsCount++;
if(Check20()) break;
}
if(Check20()) break;
....
//others conditions that increment ErrorsCount
if(Check20()) break;
}
}
private bool Check20()
{
if(ErrorsCount==20)
{
ValidationComplete();
return true;
}
return false;
}
If you dislike all that repetition, you can create a small function for it too.

Throw a custom exception inside the ErrorsCount setter (or better yet, create an IncrementErrorCount() method) when ErrorCount reaches 20. Then catch it and return.
try {
...
IncrementErrorCount();
...
} catch(TooManyErrorsException) {
return;
}
It is a bit of an anti-pattern of using exceptions for control throw, but if this is an exceptional circumstance, and if this is a client app and this doesn't happen in a loop, it is ok.

Another approach: it's hard to tell from your abbreviated code, but if all your checks are in loops, you may also be able to put the check into the for loop condition:
for(...; oldCondition && ErrorCount < 20; ...) {
}
ValidationComplete();

Related

c# unity Renewing while loop

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

exiting C# function execution if one of the variable value during execution becomes true

I have a function Parent() and a boolean Class Property Watch with default value true.
This fn Parent() is calling several Child functions.
Lets assume during execution of this function or any of the child functions Watch Changes its value to false , i want the execution to stop and exit the Parent function.
Parent is returning void.
This is a single threaded execution , no async and Task constructs being used
I think the easiest thing to do is to use exceptions for this:
public class TestClass
{
public void ParentMethod()
{
try
{
ChildMethod1();
ChildMethod2();
}
catch (InvalidStateException ise)
{
return;
}
}
public void ChildMethod1()
{
//do stuff, and then if the "watch" is set to true:
throw new InvalidStateException();
}
public void ChildMethod2()
{
//do stuff, and then if the "watch" is set to true:
throw new InvalidStateException();
}
}
public class InvalidStateException : Exception { }
Here I've defined a new exception InvalidStateException that the ChildMethodX can raise when it wants the parent method to stop execution. In the parent method you try/catch all the child calls, and when one throws, it stops the execution and skips into the catch.
Note: Exceptions occur because something exceptional happens. If you expect that this would be a normal flow of logic, then I would implore you to try something that avoids exceptions. Exceptions are expensive performance wise. For example, without using exceptions you could do something like:
public class TestClass
{
public bool Watch { get; set; }
public void ParentMethod()
{
Func<bool> c1Call = () => { Child1Method(); return Watch; };
Func<bool> c2Call = () => { ChildMethod2(); return Watch; };
if (c1Call())
return;
if (c2Call())
return;
}
public void Child1Method()
{
//Do something, then this happens:
Watch = true;
}
public void ChildMethod2()
{
//Do something, then maybe this happens:
Watch = true;
}
}
Where you could modify the Func<> delegates to take any number of arguments. There are a dozen ways to skin this cat, but almost all of them involve checking the flag after calling the function to determine if you want to exit or not. If you functions return void, consider changing them to return bool so you could do something like:
if (ChildMethod1()) return;
Which is pretty concise. Otherwise you can use strange combinations of lambda's and delegates, but when you get down to it you have to ask yourself, is avoiding typing a couple extra "if" statements worth the loss in code maintainability?
Here is a demo mock up how you can construct that.
It demonstrates a workflow where Child2 sets the variable to false and exits after that and therefore never executed Child3.
However I would suggest to have the child functions return a bool instead. Seems not a good design what you are suggesting for a single threaded application.
public class Test
{
public bool Watch { get; set; }
public Test()
{
this.Watch = true;
}
public void Parent()
{
this.Child1();
if(this.Watch == false)
{
return;
}
this.Child2();
if(this.Watch == false)
{
return;
}
this.Child3();
if(this.Watch == false)
{
return;
}
}
public void Child1()
{
//Do stuff
}
public void Child2()
{
this.Watch = false;
}
public void Child3()
{
//Do stuff
}
}
You can either execute each Child function in a different thread and have a loop in the Parent function monitor the Watch value or you can check the Watch value after each Child call. Without a code example or more information, it is difficult to answer.
fn Parent()
{
childfn();
if( !Watch )
return;
}
Though might be better to have child functions return bool and check that rather than use class property.
i assume this is yr code structure.. if my assumption is wrong please correct me
I also have a question - all the child functions have same signature ? if so I'll suggest approach based on delegates. Otherwise here is a simple example
bool Watch { get; set; }
// Parent is control center, calling one child after another
void Parent()
{
ChildOne(1);
if (Watch == false)
return;
ChildTwo(1,3);
if (Watch == false)
return;
}
/// signature type 1
void ChildOne(int a)
{
}
/// signature type 2
void ChildTwo(int a, int b)
{
Watch = false;
}
EDIT 1
here is the approach if all functions have same signature
class ChildFuntionExecutor
{
public Func<int,int> ChildFuntion;
public int Operand1;
public void Evaluate()
{
ChildFuntion(Operand1);
}
}
bool Watch { get; set; }
// Parent is control center, calling one child after another
void Parent()
{
// register all child functions
List<ChildFuntionExecutor> childFuntionQueue = new List<ChildFuntionExecutor>();
childFuntionQueue.Add(new ChildFuntionExecutor { Operand1 = 10, ChildFuntion = this.ChildOne });
childFuntionQueue.Add(new ChildFuntionExecutor { Operand1 = 10, ChildFuntion = this.ChildOne });
foreach (var item in childFuntionQueue)
{
item.Evaluate();
if (Watch == false)
return;
}
}
/// signature type 1
int ChildOne(int a)
{
return a * 10;
}
/// signature type 1
int ChildTwo(int a)
{
Watch = false;
return a * 10;
}

How to break out of an IF statement

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);
}

How to properly notify caller on failure of the asynchronous operation?

Class FeatureManager manages some feature and looks something like this:
public class FeatureManager
{
public event EventHandler FeatureEnabledChangedEvent;
private void OnFeatureEnabledChanged()
{
if (FeatureEnabledChangedEvent != null)
{
FeatureEnabledChangedEvent(this, EventArgs.Empty);
}
}
public event EventHandler FeatureEnableBusyChangedEvent;
private void OnFeatureEnableBusyChanged()
{
if (FeatureEnableBusyChangedEvent != null)
{
FeatureEnableBusyChangedEvent(this, EventArgs.Empty);
}
}
public event EventHandler FeatureEnableFailedEvent;
private void OnFeatureEnableFailed(FeatureEnableFailedEventArgs args)
{
if (FeatureEnableFailedEvent!= null)
{
FeatureEnableFailedEvent(this, args);
}
}
private bool _isFeatureEnabled
public bool IsFeatureEnabled
{
get
{
return _isFeatureEnabled;
}
private set
{
if (_isFeatureEnabled != value)
{
_isFeatureEnabled = value;
OnFeatureEnabledChanged();
}
}
}
private bool _isFeatureEnableBusy;
public bool IsFeatureEnableBusy
{
get
{
return _isFeatureEnableBusy;
}
private set
{
if (_isFeatureEnableBusy != value)
{
_isFeatureEnableBusy = value;
OnFeatureEnableBusyChanged();
}
}
}
public async Task EnableFeature()
{
IsFeatureEnableBusy = true;
try
{
// By its nature, process of enabling this feature is asynchronous.
await EnableFeatureImpl(); // can throw exception
IsFeatureEnabled = true;
}
catch(Exception exc)
{
OnFeatureEnableFailed(new FeatureEnableFailedEventArgs(exc.Message));
}
finally
{
IsFeatureEnableBusy = false;
}
}
}
UI class FeatureView has to be notified when:
IsFeatureEnableBusy changes (or, in other words when EnableFeature is being executed - in order to disable some controls)
IsFeatureEnabled changes
EnableFeature fails (when it throws exception in which case FeatureView displays error message
to the user)
EnableFeature can be called from some Engine class E (automatically, during the initialization on the application's launch) and also from FeatureView (when user presses 'Enable' button).
In order to satisfy requirement where FeatureView has to be notified when EnableFeature fails after it's been called by E, I added an event FeatureEnableFailedEvent.
When E calls EnableFeature and EnableFeature throws an exception, FeatureView receives FeatureEnableFailedEvent and displays error message. But when FeatureView itself calls EnableFeature and EnableFeature fails, FeatureView catches thrown exception but also gets notified on this failure from FeatureEnableFailedEvent so error handler is called twice. How to avoid this?
One solution is to declare EnableFeature as an old-style async method (and use BackgroundWorker) as in the following snippet:
public class FeatureManager
{
public void EnableFeatureAsync()
{
var bgw = new BackgroundWorker();
bgw.DoWork += (sender, e) =>
{
IsFeatureEnableBusy = true;
EnableFeatureImpl(); // can throw exception
};
bgw.RunWorkerCompleted += (sender, args) =>
{
IsFeatureEnableBusy = false;
if (args.Error == null)
{
IsFeatureEnabled = true;
}
else
{
OnFeatureEnableFailed(new FeatureEnableFailedEventArgs(args.Error.Message));
}
};
bgw.RunWorkerAsync();
}
}
In this case, caller of EnableFeatureAsync can assume that this method runs asynchronously (suffix Async in method's name should be a hint) and that it has to subscribe to FeatureEnableFailedEvent if want to be notified on the method failure. This way FeatureView gets notified on EnableFeatureAsync failure only once so error handler is called once as it should be.
Is this a good approach? Could this be achieved by still using async/await in some way? Is it good assuming that suffix Async in method's name is a good enough hint to callers so they know that this method runs as asynchronous one and that they have to look for some events to subscribe to?
As commented by #svick, I also don't see why your FeatureView catches the exception and also gets the event, when the exception is not rethrown in the handler of FeatureManager. But here is an different approach, which I'd prefer over yours based on events:
Use TaskCompletionSource to let the view know when the enablement of a feature did throw an exception even when FeatureView is not the caller of EnableFeature() (btw, by convention the method should also be named EnableFeatureAsync in the first example).
public class FeatureManager
{
public TaskCompletionSource<bool> FeatureCompleted { get; private set; }
// if you still need this property
public bool IsFeatureEnabled
{
get { return FeatureCompleted.Task.IsCompleted; }
}
public FeatureManager() {}
public async Task EnableFeature()
{
IsFeatureEnableBusy = true;
try
{
// By its nature, process of enabling this feature is asynchronous.
await EnableFeatureImpl(); // can throw exception
this.FeatureCompleted.TrySetResult(true);
}
catch(Exception exc)
{
this.FeatureCompleted.TrySetException(exc);
}
finally
{
IsFeatureEnableBusy = false;
}
}
}
Your FeatureView instance now needs to await the Task of the TaskCompletionSource. The code could look like this:
public class FeatureView
{
// if you still need this property
public async void HandleFeatureCompleted(FeatureManager fm)
{
try
{
await fm.FeatureCompleted.Task;
}
catch(Exception e)
{
// handle exception
}
}
}
You have to provide the correct FeatureManager instance to your view. I'm not sure if this approach is appropriate if you have hundredths or even thousands of FeatureManager instances messages. I'd be happy if more somebody of the commenters could provide feedback about this.

Is this a safe way to execute threads alternatively?

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.

Categories

Resources