How to execute a method Once during Runtime on c# - c#

Is there a possibility to prevent method execution more than once during Run-time of an Instance without using an external Attribute ?
I hope i was clear !
Bests

Try using a static constructor

public class TestClass
{
static private bool _isExecutedFirst = false;
public void MethodABC()
{
if(!_isExecutedFirst)
_isExecutedFirst = true;
else
throw Exception("Method executed before");
/////your code
}
}
Hope this help

sure, with a flag to indicate whether a method on an instance has been run.
public class RunOnceMethod
{
private bool haveIRunMyMethod = false
public void ICanOnlyRunOnce()
{
if(haveIRunMyMethod)
throw new InvalidOperationException("ICanOnlyRunOnce can only run once");
// do something interesting
this.haveIRunMyMethod = true;
}
}

Yes,
you can use like this
void method(args)
{
static int a;
if(a != 0)
{
return;
}
// body of method and
a++;
}
reason being this static a will not be copied to activation records of the function calls and all will share only one a.
I hope this resolve your question.

No, there is no way to prevent method execution without storing some kind of 'state' saying the method has already been executed.
One way of doing this is a "guard" / check at start:
private bool AExecuted = false;
public void A()
{
if (AExecuted)
return;
else
AExecuted = true;
/* Your code */
}

Related

auto property get and set is not working inside callback method c#

Hi I am simply trying to get the value from a static auto property as below -
Here is my class -
public class ShutdownService
{
private const int TimerInterval = 6000;
private static DateTime _midnightStartTime;
public static bool TimeForMidNightShutDown{get; set;}
public static void Start(){
_midnightStartTime = DateTime.Now.AddMinutes(4);
_timer = new Timer(StartTask, null, 0, TimerInterval);
}
public static void StartTask(object state){
if(DateTime.Now >= _midnightStartTime){
TimeForMidNightShutDown = true;
} else {
TimeForMidNightShutDown = false;
}
}
}
I am calling this start method when I am starting the application. if I put a debug point on if(DateTime.Now >= _midnightStartTime), it's making TimeForMidNightShutDown property value as true. But when I call this property from other class by ShutdownService.TimeForMidNightShutDown, it's always returning me as false. I am not sure what am I missing here. Could you please guide?
I don't exactly know why the static stuff is not working. So instead of offering wrong clues I would like to give you a working example without using static, which maybe caused your problem:
public class ShutdownService
{
private const int TimerInterval = 6000;
private DateTime _midnightStartTime;
private bool disposerFlag;
public bool TimeForMidNightShutDown{get; set;}
public void Start(){
_midnightStartTime = DateTime.Now.AddMinutes(1);
var _timer = new Timer(StartTask, null, 0, TimerInterval);
while (!disposerFlag)
{
}
_timer.Dispose();
}
public void StartTask(object state)
{
if(DateTime.Now >= _midnightStartTime)
{
TimeForMidNightShutDown = true;
Console.WriteLine("true");
disposerFlag = true;
}
else
{
TimeForMidNightShutDown = false;
Console.WriteLine("false");
}
}
}
This code can be than executed over the Programm.cs in the main method with
new ShutdownService().Start();
The empty while loop is quite important since the programm won't wait for the timer to finish his duty. I am sure you could also solve it way more elegant with some async approach or also with static, but this is one fast working model here. Hope it helps. And I am totally open here for improvements.

How do I avoid repetitive if statements without interrupting event to run other actions?

There are two classes that interact in this problem. I'd like to note I'm using Unity:
TaskHandler
public class TaskHandler{
public event Action<GameObject> TaskResponses;
private void Update(){
if (someCondition){
TaskResponses?.Invoke(taskObj);
}
}
}
TaskBase
public class TaskBase: MonoBehaviour{
private TaskHandler taskHandler;
private void Start(){
taskHandler = gameObject.GetComponent<TaskHandler>();
taskHandler.TaskResponses += TaskResponse;
}
private void TaskResponse(GameObject taskObj){
//if check so that only specific TaskResponses run.
if (taskObj == gameObject){
//functions
}
}
}
The problem I'm facing is with methods that extend TaskResponse().
public class SpecificTask{
public override void TaskResponse(GameObject taskObj)
{
base.TaskResponse(taskObj);
//another if check
if (taskObj == thisTaskObj){
//some other functionality
}
}
}
I don't want to do another if check. I tried the following:
public class TaskBase: MonoBehaviour{
//Start() method omitted
private void TaskResponse(GameObject taskObj){
//if check so that only specific TaskResponses run.
if (taskObj == gameObject){
//functions
}
else{
//Effectively stops code from SpecificTask to continue running,
//But other Actions are no longer called.
return;
}
}
}
But the return statement stops TaskReponses() from other classes to run. By that, I mean that if I had Class Task1 and Task2, and Task1's TaskResponse() runs first, but it runs the else statement, it stops and does not run Task2's TaskResponse().
How can I improve my code to stop writing repetitive if checks, while have my code check all Action like I want it to? Should I not be using event for this scenario at all?
Thank you!
You could make it not void but rather bool which indicates if the method was successfully terminated or aborted like e.g.
public class TaskBase
{
public virtual bool TaskResponse(GameObject taskObj)
{
if(taskObj != thisObj) return false;
// Default stuff to happen
return true;
}
}
Then you can do
public class MyTask
{
public override bool TaskResponse (GameObject taskObj)
{
if(!base.TaskResponse(taskObj)) return false;
// Default stuff already happened
// Now you can add additional stuff here
return true;
}
}
Alternatively if you want to avoid that if check entirely what I also do often is using separate methods like
public class TaskBase
{
public void TaskResponse (GameObject taskObj)
{
if(taskObj != thisObj) return;
TaskResponseInternal();
}
protected virtual void TaskResponseInternal()
{
// Default stuff to happen
}
}
And then simply override that instead
public class MyTask
{
protected override void TaskResponseInternal ()
{
// If you want also the default stuff
base.TaskResponseInternal();
// Additional stuff to happen
}
}

prevent method execution on design time using attributes

Is there a way to prevent a method from execution if it is in design time or the method can only be executed at runtime.
I got this problem while creating a custom control because there is a method call in the constructor that will only work at runtime.
now at design time while designing the form and use that control, then the form will generate the error.
now i tried this at the constructor of the user control
public ctrl_information()
{
InitializeComponent();
if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)) return;
SomeMethod();
//Other code
}
what i want to achieve now is something like this.
[ExecuteOnlyAtRuntime]
public void SomeMethod()
{
//Code here
}
Then call it like this.
public ctrl_information()
{
InitializeComponent();
//if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)) return; -- removing this line
SomeMethod();
}
Is it possible?
Please shed some light on this.
Thank you
Assuming that someMethod is in a control, you may use Component.DesignMode.
So a simple approach could be
public void SomeMethod()
{
if (this.DesignMode == false)
{
//Code here
}
}
Incase the Some function is not in a control, you may implement something like this -
public void SomeFunciton()
{
if(VisualStudioUtility.IsRunningInVisualStudio == false)
{
}
}
static class VisualStudioUtility
{
private const string IDE_EXE = "devenv.exe";
public static bool IsRunningInVisualStudio
{
get
{
return Environment.CommandLine.Contains(IDE_EXE);
}
}
}

C# Set Variable in Thread

I'm trying to work with Threads for a private Project and I have a question which is, as I think very easy to answer.
Is it possible to set a variable in another thread?
Here a little Code example to show you what I'm trying to do:
public class PartyClass
{
public boolean partytime = true;
public void MakeParty()
{
while(partytime)
Console.WriteLine("I'm making a party here");
Console.WriteLine("The party ended. Please leave now");
}
public void StopParty()
{
partytime = false;
}
}
public class MainThread
{
public static int Main(String[] args)
{
PartyClass party = new PartyClass();
Thread partyThread = new Thread(new ThreadStart(party.MakeParty()));
partyThread.Start();
while (!partyThread.IsAlive) ;
System.Threading.Thread.Sleep(5000);
// Now I want to somehow call the StopParty() Method
}
}
I don't know if it's really stupid what I'm trying to do but I think its a nice way to stop the "Partythread" in a clean way.
Is this possible or is there a better solution for this?
Thanks for your Ideas.
(I didn't test the Code - just wrote it out of my head)
You call the stop method just the way you called the start method:
party.StopParty();
In order to ensure that the changes made in another thread aren't just cached, the partytime field should be marked as volatile as well.
You should use synchronization facilities, such as CancellationToken.
Your code will look like:
public class PartyClass
{
private readonly CancellationToken _cancellationToken;
public PartyClass(CancellationToken cancellationToken)
{
_cancellationToken = cancellationToken;
}
public void MakeParty()
{
while (!_cancellationToken.IsCancellationRequested)
Console.WriteLine("I'm making a party here");
Console.WriteLine("The party ended. Please leave now");
}
}
public class MainThread
{
public static int Main(String[] args)
{
var cancellationSource = new CancellationTokenSource();
PartyClass party = new PartyClass(cancellationSource.Token);
Thread partyThread = new Thread(party.MakeParty);
partyThread.Start();
System.Threading.Thread.Sleep(5000);
cancellationSource.Cancel();
partyThread.Join();
}
}
It is thread-safe and suitable not only for this, but also for more advanced scenarios, as well as for working with tasks.
If want more threads to ask for the same variable, take care about thread syncrhonization issues (when two threads try to access the same variable).
Im going to show the safest way (might be more than what you need). The best to way to do it is declaring an static object to set a lock in order to make sure you have one thread changing the party flag at once.
public class PartyClass
{
private object _partyTimeLock = new Object(); // executed at class init
private boolean partyTime= true;
public bool IsPartyGoingOn()
{
bool itIsGoingOn = false;
lock(_partyTimeLock) {
itIsGoingOn = partyTime;
}
return itIsGoingOn;
}
public void StopParty()
{
lock(_partyTimeLock) {
partyTime = false;
}
}
public void MakeParty()
{
while(IsPartyGoingOn()) {
Console.WriteLine("I'm making a party here");
}
Console.WriteLine("The party ended. Please leave now");
}
}
In this example here, no matter who try to call the IsPartyGoingOn(), you will never have an issue (no matter if it the class own thread or another one). The lock keyword will guarantee you are doing the right way.

Passing parameter between classes via delegates or...?

I'd need to pass some variables between classes, I have a following code snippet to explain the situation. Note the following code are from app1, the SimpleScene() class is the entry point.
class SimpleScene {
bool isReady;
bool result;
Protected override Run() {
// instance of class StateMonitor
StateMonitor sm = new StateMonitor;
Listener(sm);
sm.proc();
while(!isReady) {}
result = func();
if (result) {
// need to inform StateMonitor to do a certain action, e.g. set bool flag = true, and StateMonitor does something iff flag == true;
}
}
void OnReady(bool isOnReady) {
if(isOnReady)
isReady = true;
}
Private void Listener(StateMonitor sm) {
sm.OnReady += new StateMonitor.ready(OnReady);
}
bool func() {
//do something...
}
}
class StateMonitor {
public delegates void ready(bool isReady);
public event ready OnReady;
// start app2 as a new process
public void proc() {
Process p_app2 = new Process();
// omit other startinfo for app2.
p_app2.OutputDataReceived += new DataReceivedEventHandler(outputHandler);
p_app2.Start();
p_app2.BeginOutputReadLine();
}
public void outputHandler(object sender, DataReceivedEventArgs line) {
// omit output data line match
if (OnReady != null)
OnReady(true);
}
}
class StateMonitor starts another application - let's say app2 - and read the stdout from app2. Depending on the output string format, it will do different things.
My problem lies in the code comments, where I want to inform StateMonitor to do certain thing once flag == true; How could I do that?
Thank you
You're going to want to use threads. You'll fire off a thread in StateMonitor that loops based on a boolean. Then set that boolean from SimpleScene when you want to do something when that flag is true. There are tons of examples out there. Check here:
http://msdn.microsoft.com/en-us/library/7a2f3ay4(v=vs.90).aspx
Worker = StateMonitor
WorkerThreadExample = SimpleScene

Categories