Check value for 2 second - c#

i have an integer whose value changes, i like to know if there is a way to check whether the value is same for 2 sec.
like if num = 2 for 2 sec then Messagebox.show("for 2 sec");
cause my numbers are changing instantly.

How about make it keep track of when it last changed?
int _num;
public int num
{
get { return _num; }
set
{
if(value != _num)
{
_num = value;
numModified = DateTime.Now;
}
}
}
public DateTime numModified { get; private set; }

This might be superfluous, I like using DispatcherTimer. This will tick every 2 seconds to look for a change:
private DispatcherTimer _checkNumberTimer = null;
private int _myNumber = int.MinValue;
private int _lastValue = int.MaxValue;
public Constructor1(){
_checkNumberTimer = new DispatcherTimer();
_checkNumberTimer.Tick += new System.EventHandler(HandleCheckNumberTick);
_checkNumberTimer.Interval = new TimeSpan(0, 0, 0, 2); //Timespan of 2 seconds
_checkNumberTimer.Start();
}
private void HandleLoginOrderDispatcherTick(object sender, System.EventArgs e) {
if(_myNumber == _lastValue){
MessageBox.Show("Alert!");
_checkNumberTimer.Stop(); //If you want
}
_lastValue = _myNumber;
}
private void SomeOtherCodeAffectingMyNumber(int something){
_myNumber = something;
}
You would need to include System.Windows.Threading.
The good thing about DispatcherTimer is that it handles all the work of delegating to the UI thread.

Consider implementing INotifyPropetyChanged interface from System.ComponentModel - here is the description with example.

Try to create a property, a Bool, buffer and a Timer. Now change the setter like this:
public int Variable
{
get { return _variable; }
set
{
yourtimer.Stop();
IsLongerThanTwoSec = false;
_variable = value;
yourtimer.Start();
}
}
Create a timer like this and set this .Elapsed:
bool IsLongerThanTwoSec = false;
Timer timer = new Timer(2000);
timer.Elapsed += (e, s) => IsLongerThanTwoSec = true;
if IsLongerThanTwoSec is false it is not; otherwise, it is.

Related

How to use static timer on a linked list?

I'm creating a linked list of objects holding a time. the linked list is sorted by that time, which mean that the most early item would be first. with in the class holding the linked list i keep a timer that should operate always on the first item in the list. when the event of the timer is done, the first item is removed, and the timer restart with the interval set by the new first item's time. the same happened if an item with an earlier time than the first item is being inserted. the error: when i run the program with 2 items in the list the Elapsed event occurring 3 times, and therefore i get the error this
System.NullReferenceException: 'Object reference not set to an instance of an object.'
System.Collections.Generic.LinkedList.First.get returned null.
because the first item has been removed and the event try to print it's id.
my question is why the third event happened in the first place, since the timer shouldn't be activated if there is no items in the list
. this is the item class:
public class TimerItem : IComparable<TimerItem>
{
public int Id { get; }
private readonly DateTime ResultTime;
public TimerItem (int id, DateTime resultTime)
{
Id = id;
ResultTime = resultTime;
}
public double MilliSecondsCountToCompletion
{
get
{
if (ResultTime.Subtract(DateTime.Now).Seconds > 0)
{
return ResultTime.Subtract(DateTime.Now).TotalMilliseconds;
}
return 1;
}
}
public int CompareTo(TimerItem other)
{
if (ResultTime < other.ResultTime)
{
return -1;
}
if (ResultTime == other.ResultTime)
{
return 0;
}
else
return 1;
}
}
this is the class holding the linked list:
public static class TimersManager
{
private static LinkedList<TimerItem > TimerItems = new LinkedList<TimerItem>();
private static Timer _timer = new Timer();
public static void Add(TimerItem timerItem )
{
if (TimerItems.First == null || TimerItems.First.Value.CompareTo(timerItem ) > 0)
{
TimerItems.AddFirst(timerItem);
SetTimerToFirst();
}
else
{
var temp = TimerItems.First;
while (temp.Next != null && temp.Next.Value.CompareTo(timerItem) <= 0)
{
temp = temp.Next;
}
TimerItems.AddAfter(temp, timerItem);
}
}
private static void Completed(Object sender, EventArgs e)
{
_timer.Stop();
Console.WriteLine(TimerItems.First.Value.Id);
TimerItems.RemoveFirst();
if (TimerItems.First != null)
{
SetTimerToFirst();
}
}
private static void SetTimerToFirst()
{
_timer.Interval = TimerItems.First.Value.MilliSecondsCountToCompletion;
_timer.AutoReset = false;
_timer.Elapsed += Completed;
_timer.Start();
}
}
Simply adding :
_timer.Elapsed -= Completed;
to the Completed method solved the problem

Change data in Class when List<sub-class> data is changed

I have a class STimer that has a List in it. The serviceDetail is monitored on a timer very often, and rarely changes, but when it does change I want to get the fact that the data changed without looping through the list due to processing power. Maybe this is a duplicate question that I just don't know how to search for it, but I have been trying. Here is a code Sample:
class STimers
{
public class ServiceDetail
{
private int _serviceKey;
private bool _isRunning = true;
private bool _runningStateChanged = false;
public bool isRunning
{
get { return _isRunning; }
set
{
//Check to see if the data is the same, if so, don't change, if not, change and flag as changed
if(_isRunning = value) { return; }
else
{
_isRunning = value;
_runningStateChanged = true;
<-- Update STimers._dataChanged to true -->
}
}
}
}
public List<ServiceDetail> _serviceMonitors = new List<ServiceDetail>();
public bool _dataChanged = false;
}
I could do a .Find on the list to return all of the _serviceMonitors._runningStateChanged=true, but that seems like a lot of work parsing the List every time the timer fires, when likely only 1 out of 1,000 loops will actually have a change.
Is this even possible, or do I need to move the check for changes out of the class?
You could get this by adding an event to your ServiceDetail class
public class ServiceDetail
{
public event EventHandler<ListChangedEventArgs> ListChanged;
private int _serviceKey;
private bool _isRunning = true;
private bool _runningStateChanged = false;
private void OnListChanged(ListChangedEventArgs e){
if (ListChanged != null) ListChanged(this, e);
}
public bool isRunning
{
get { return _isRunning; }
set
{
//Check to see if the data is the same, if so, don't change, if not, change and flag as changed
if(_isRunning = value) { return; }
else
{
_isRunning = value;
_runningStateChanged = true;
OnListChanged(new ListChangedEventArgs(this));
<-- Update STimers._dataChanged to true -->
}
}
}
}
And define your ListChangedEventArgs class like this
public class ListChangedEventArgs:EventArgs
{
public ServiceDetail serviceDetail { get; set; }
public ListChangedEventArgs(ServiceDetail s)
{
serviceDetail = s;
}
}
And then register to the event for each servicedetail added to the list
s.ListChanged += (sender, args) => YourFunction();
Hope it helps

Use one windows form to increment progress bar of another form

I was just wondering if I have a form Form1, and declare
public partial class Form1 : Form
{
GraphLoadProgress loadProgress;
public Form1()
{
loadProgress = new GraphLoadProgress();
loadProgress.Show();
// do some stuff
loadProgress.progress = 25; // increment by 25%
// more stuff
for (int i = 0; i < 65; i++) // increment by 65%
{
loadProgress.progress = 1;
}
// even more stuff
loadProgress.progress = 10; // increment by 10%
// blah blah
loadProgress.progress = 100; // make sure it goes over 100%
}
}
and in my GraphLoadProgress form is the following
public partial class GraphLoadProgress : Form
{
public int progress { get; set; }
private void StartBackgroundWork()
{
if (Application.RenderWithVisualStyles)
progressBar.Style = ProgressBarStyle.Marquee;
else
{
progressBar.Style = ProgressBarStyle.Continuous;
progressBar.Maximum = 100;
progressBar.Value = 0;
timer1.Enabled = true;
}
//backgroundWorker.RunWorkerAsync();
}
private void timer1_Tick(object sender, EventArgs e)
{
if (progressBar.Value > progressBar.Maximum)
this.Close();
progressBar.Increment(progress);
}
}
This obviously does not work because the timer will update and increment even when i did not want it to, is there any way to increment the progress bar, and only increment with by a certain amount while the progress bar is still updating?
You could use the setter of the progress property directly, something like:
private int _progress = 0;
public int progress {
get { return _progress; }
set {
_progress = value;
if (progressBar.InvokeRequired) {
this.Invoke((MethodInvoker) delegate {progressBar.Value == value;});
} else {
progressBar.Value = value;
}
}
}
That way you can set from outside what the value of the progressbar should be. The InvokeRequired check makes it possible to set the value from a different thread.
More closely mimicing the behaviour you have would be a WriteOnly property (only a setter):
public int progress {
set {
if (progressBar.InvokeRequired) {
this.Invoke((MethodInvoker) delegate {progressBar.Increment(value);});
} else {
progressBar.Increment(value);
}
}
}
Also you can always just add a public Increment method to the form.
public void IncrementProgress(int Value)
{
if (progressBar.InvokeRequired) {
this.Invoke((MethodInvoker) delegate {progressBar.Increment(Value);});
} else {
progressBar.Increment(Value);
}
}
You should add checks for the Maximum value in any case, to avoid exceptions.

Having multiple properties incrementing one variable. Simple check of its value?

I have 10 properties where when each is set it increments the value of variable Value. When the value of Value is 10, the app will end. But it seems to be awkward to write the same condition into each of them like this:
int Value=0;
int A
{
set
{
a=value;
Value++;
if(Value>10) ... //check here
}
}
int B
{
set
{
b=value;
Value++;
if(Value>10) //check here again
}
}
How can I simplify checking its value?
You could make a private property for Value and in the setter of that property, if the value is set to above 10, exit the application.
private int value=0;
private int a, b;
public int A
{
set
{
this.a = value;
Value++;
}
get { return this.a; }
}
public int B
{
set
{
this.b = value;
Value++;
}
get { return this.b; }
}
private int Value
{
set
{
this.value = value;
if (this.value > 10)
{
// Exit.
}
}
get { return this.value; }
}
I'm assuming that your properties are in a class which has other responsibilities than exiting the program when the counter hits 10. If so, I would remove the logic of checking the counter and exiting the app from the class.
Maybe you can use an event. The subscriber to this event will be notified when Value hits 10 (you could actually make "10" configurable, but this is just a short example) and exit the app.
class YourClass {
public event ValueHandler ValueIs10;
public EventArgs e = null;
public delegate void ValueHandler(YourClass m, EventArgs e);
private int _value=0;
public int Value {
get {return _value;}
private set {
_value=value;
if(_value==10 && ValueIs10 != null) ValueIs10(this, e);
}
}
public int A
{
set
{
a=value;
Value++;
}
}
public int B
{
set
{
b=value;
Value++;
}
}
// ...
}
private int counter;
private int b;
private int a;
public int A
{
set
{
counter++;
a = value;
CheckCounter();
}
}
public int B {
set
{
counter++;
b = value;
CheckCounter();
}
}
public void CheckCounter()
{
if (counter>10)
{
//Do something
}
}
or make counter a property..
private int Counter
{
set
{
counter = value;
CheckCounter();
}
get
{
return counter;
}
}
and use this when incrementing..
Counter++;
Both answers from #Richard and #Emil are correct, but to make your code more expandable in the future, it's better to implement the built-in INotifyPropertyChanged interface.
class Data : INotifyPropertyChanged
{
private int _counter = 0;
public event PropertyChangedEventHandler PropertyChanged = (sender, arg) =>
{
// if (_counter > 10) Exit();
// from arg you can know what property is changed
// which is probably used for future
};
private int _number;
public int Number
{
get { return _number; }
set
{
//here is another unclear point in your question
//will the counter increases when setting a.Number = 100
//but it's already 100 before setting
if (_number != value)
{
_number = value;
PropertyChanged(this, new PropertyChangedEventArgs("Number"));
}
}
}
}

How to lock/unlock a field at runtime in C#?

Can I lock/unlock fields or objects at runtime against writing? In other words something like changing objects to read-only temporarily at runtime...
For example:
int x = 5; // x is 5
LockObject(x);
x = 7; // no change
UnlockObject(x);
x = 10; // x is 10
if not can you give me some possible solutions?
You can use accessors to do this...
public class X
{
private bool locked = false;
private int lockedVar;
public int LockedVar
{
get { return lockedVar; }
set { if (!locked) lockedVar = value; }
}
public void LockObject() { locked = true; }
public void UnlockObject() { locked = false; }
}
Wrap it in a property and then use a boolean flag as the "lock".
You can also use a struct to handle this type of logic.
public struct LockableInt
{
private int _value;
public bool Locked;
public void Lock(bool locked) {Locked = locked;}
public int Value
{
get
{ return _value; }
set
{ if (!Locked) _value = value; }
}
public override string ToString()
{
return _value.ToString();
}
}
Sample client code:
public static void RunSnippet()
{
LockableInt li = new LockableInt();
li.Value = 5;
Console.WriteLine(li.ToString());
li.Lock(true);
li.Value = 6;
Console.WriteLine(li.ToString());
li.Lock(false);
li.Value = 7;
Console.WriteLine(li.ToString());
}
Output:
5
5
7
Press any key to continue...
Thanks all for help. Here is a more generalized alternative.
I have decided that it would be more convenient to use freeze/unfreeze since lock/unlock exists in the context of multithreading programming.
public class FreezeableValue<T>
{
private bool frozen;
private T value;
public FreezeableValue()
{
frozen = false;
}
public FreezeableValue(T value)
{
this.value = value;
frozen = false;
}
public void Freeze(bool frozen)
{
this.frozen = frozen;
}
public T Value
{
get { return value; }
set
{
if (!frozen) this.value = value;
}
}
}

Categories

Resources