Hello i want to ask how to modifiying value static variable from static callback, and read value again. I need to stop while looping when value from static variable change. This is my code.
The problem is value from stepControlEx remain same, it doesnt change when another callback run again and modify the value. It makes my looping stuck and cannot end.
Thanks for helping
Private static int stepControl = 0;
Private static int stepControlEx
{
get { return stepControl;}
set { stepControl = value;}
}
Private static void CallbackHandle (Object object)
{
If (object == 0)
{
stepControlEx = 0;
While (stepControlEx == 0)
{
//do events
//stop when stepControl Change
}
}
Else If (object == 1)
{
stepControlEx = 1;
While (stepControlEx == 1)
{
//do events
//stop when stepControl Change
}
}
}
EDITED (SOLVED):
I tottaly change the algorithm and use thread that process data from queue. Callback function only enqueue input to queue and thread dequeue input to processing, now step control doesn't need as global variable. Thank you
Your code looks ambiguous. But I have only one comment for your code. If you have a static variable and shared among multiple threads, you need to lock the variable while changing it.
I think you get deadlocks that is why the loop never ends.
Anytime you assign any static variable in a multi-threading environment. you need to to this:
lock (new object())
{
stepControlEx = 0;
}
Related
I have a method which is been called every 1 hour. But sometimes the method operations are not been completed fully within one hour and the method is again been called which causes confusion. So I have to find out if the previous method is been completed. Which is the best solution for this problem?
// will be called for every one hour where the value will be repeated
// At sometimes it is possible for the same value to be called continually
for the next hour and at that time problem occurs
Void Method(int value)
{
If(value =0)
// Do some operations which may exceed one hour
Else If(value =1)
// Do some operation’s which may exceed one hour
.
.
.
}
Thanks,
One question would be what do you want to happen if the method is called while it is still running?
This code will just drop the 2nd call
private bool _running = false;
private readonly object _lock = new object();
void Method(int value)
{
lock (_lock)
{
if (_running)
{
return;
}
else
{
_running = true;
}
}
if (value == 0)
{
// Do some operations which may exceed one hour
}
else if (value == 1)
{
// Do some operation’s which may exceed one hour
}
_running = false;
}
A simple idea is to save the state in a class field, so that the method checks to see if it's free to do some work or not. This will mean that if you call the method and it's busy, the work won't happen for your call:
private static bool methodIsBusy = false;
private static void WaitAndWriteMessage(TimeSpan waitTime, string message)
{
// If we're busy, return right away
if (methodIsBusy) return;
// Let future calls know we're busy
methodIsBusy = true;
Thread.Sleep(waitTime);
Console.Write($"Method ran at: {DateTime.Now.ToString("hh:mm:ss")}. ");
Console.WriteLine(message);
// Allow future calls to run now
methodIsBusy = false;
}
Our test method:
private static void Main()
{
for(int i = 0; i < 3; i++)
{
Task.Run(() => WaitAndWriteMessage(TimeSpan.FromSeconds(5),
$"Method called at {DateTime.Now.ToString("hh:mm:ss")}."));
Thread.Sleep(1000);
}
Console.ReadKey();
GetKeyFromUser("\nDone!\nPress any key to exit...");
}
Output
(Only the first of the three messages was printed)
Another idea is to use a lock, which means that calls to the method will pile up if the method is busy. All calls will eventually get completed, but if every call is longer than the iteration time in which the method is called, it will get further and further behind:
private static object methodLocker = new object();
private static void WaitAndWriteMessage(TimeSpan waitTime, string message)
{
// Lock on a common object, so this call will wait
// until there are no locks before it can continue
lock (methodLocker)
{
Thread.Sleep(waitTime);
Console.Write($"Method ran at: {DateTime.Now.ToString("hh:mm:ss")}. ");
Console.WriteLine(message);
}
}
Our test method again:
private static void Main()
{
for(int i = 0; i < 3; i++)
{
Task.Run(() => WaitAndWriteMessage(TimeSpan.FromSeconds(5),
$"Method called at {DateTime.Now.ToString("hh:mm:ss")}."));
Thread.Sleep(1000);
}
Console.ReadKey();
}
Output
(Notice the difference between when the message was called and when it executed gets longer each time)
it's the first question I ask so please be tolerant if I do something wrong.
I am writing a software to read data from a serial port a then use it to update the status of a static list of objects. Every data I receive is a communication of a wireless node and it represents its status. I solved the reading part and I am handling the search and update part.
I would like to use the background worker to search the element in the list and then update it, assuring the user a clean and smooth UI. The problem is that I read the bytes through a static function, and from that static function I should call the backgroundworker to perform the task. I read on the dotnetperls guide that "RunWorkerAsync can be called anywhere in your code.", but when I try to call it from the static function, Visual Studio doesn't let me do it.
Can anyone help me?
[edit: code added]
This is the extract of my static method:
public static void Add(Byte[] received)
{
List<byte[]> messages = new List<byte[]>();
int lastdollars = 0;
byte[] tempmess = new byte[20]; //The message is 20 digits
lock (BufferLock)
{
//I add the last bytes to the buffer (it's a list of bytes)
Buffer.AddRange(received);
if (Buffer.Count < TOTALMESSAGELENGTH) return;
String temp = Encoding.UTF8.GetString(Buffer.ToArray());
//I check the buffer to look for complete messages (there are tokens at the start and at the end
for (int i = 0; i <= (temp.Length - TOTALMESSAGELENGTH + 1); i++)
{
if ((temp.Length > i + TOTALMESSAGELENGTH) &&
(temp.Substring(i, TOKENLENGTH) == STARTTOKEN) &&
(temp.Substring((i + TOKENLENGTH + MESSAGELENGTH), TOKENLENGTH) == ENDTOKEN))
{
//if I find a message, I put it into the list of messages, I save its position and I continue to look for other messages
tempmess = Encoding.UTF8.GetBytes(temp.Substring(i, TOTALMESSAGELENGTH));
messages.Add(tempmess);
lastdollars = i;
i += TOTALMESSAGELENGTH - 1;
}
}
if (messages.Count == 0)
return;
//I delete the buffer that I'm using and I need to call the background worker
Buffer.RemoveRange(0, (lastdollars + TOTALMESSAGELENGTH));
}
worker.RunWorkerAsync(messages); //Error: An object is required for the non-static field, method, or property 'namespace.Form1.worker'
}
I tried both to define manually the backgroundworker with:
private readonly BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
and adding it through the Toolbox, but the result is the same.
You cannot access instance variables in static methods. Hence the error. Try and make the BackgroundWorker instance static. Something like the following.
private readonly static BackgroundWorker worker = new BackgroundWorker();
Not very sure if this will not break any other of your code.
Hope this helps.
This doesn't really have anything to do with BackgroundWorker or any specific class. It is just how the C# language works.
You can't access non-static members from a static function. A static function has no implicit this parameter that makes it run against a particular instance of the class. You can run it without ever creating any instances of the class.
This worker
private readonly BackgroundWorker worker = new BackgroundWorker();
will be created once for each instance of the class. But you can call the Add function without having any instances.
For example, this doesn't work for the same reason:
class Adder
{
public int sum = 0;
public static void Add(int x)
{
sum += x; // can't reference "sum" from static method!
}
}
...
Adder.Add(5)
but this works:
class Adder
{
public int sum = 0;
public void Add(int x) // no longer static
{
sum += x; // this refers to the "sum" variable of this particular instance of Adder
}
}
...
var adder = new Adder();
adder.Add(5);
and this also works (but differently!):
class Adder
{
public static int sum = 0; // we made sum static (there is exactly one, instead of a separate sum for each instance)
public static void Add(int x)
{
sum += x; // this refers to the static sum variable
}
}
...
Adder.Add(5);
I have a method that can be called from many threads, but I just want the 1st thread to do some logic inside the method. So, I'm planning to use a boolean variable. The first thread that comes in, will set the boolean variable to false (to prevent further threads to come inside), and execute the method logic.
Subsequent threads that come to this method, will check the boolean variable. Because it was set to false by the 1st thread, they will skip the method logic.
In code, something like this:
private void myMethod()
{
if (firsTime) //set to true in the constructor
{
firstTime = false; //To prevent other thread to come inside here.
//method logic
}
}
I want to use lock to perform this, but not sure where to put it.
If I lock inside the "if" to change firstTime to false, its possible 2 or more threads already come inside the if (don't want this).
If I lock outside the "if" to change firstTime to false, how can the 1st thread go inside the if to execute the method logic, if firstTime its already set to false??
My question is : how to do the lock to have the desired functionality? (1st thread that comes set the boolean and execute method logic).
I cannot lock over all the method logic, since it will be a very long time consuming operations.
You can use Interlocked.Exchange to solve this problem. It will set the value of the given variable to the specified value and return the value that used to be in the variable, and it will do it all atomically. Doing this will ensure that only one thread will ever run the code in the if:
private static int isFirst = 1;
public static void Foo()
{
if (Interlocked.Exchange(ref isFirst, 0) == 1)
{
//DoStuff
}
}
Note that Interlocked.Exchange has no overload that takes a bool, which is why you're forced to use an int (or some other type) instead, using 1 for true and 0 for false.
If you want a solution using lock, rather than Interlocked, you can do it through the use of an additional local bool value:
private static bool isFirst = true;
private static object key = new object();
public static void Foo()
{
bool amFirst;
lock (key)
{
amFirst = isFirst;
isFirst = false;
}
if (amFirst)
{
//DoStuff
}
}
I have a class that talks to an external .exe. The class has a bunch of similar methods; they call a function of the .exe, wait for response, and then return true or false.
The response comes in the form of events that change the values of fields of this class.
Simplified code:
class Manager
{
private static bool connected = false;
public static bool Connect()
{
runtime.Connect();
int secondsWaited = 0;
while (!connected)
{
Thread.Sleep(1000);
if (secondsWaited++ == 10)
{
return false;
}
}
return true;
}
}
The other methods use the same call-wait-loop-return structure.
My goal is to make a single method to do this waiting for me, like so:
private static bool WaitReferenceEqualsValue<T>(ref T reference, T value)
{
int secondsWaited = 0;
while (!reference.Equals(value))
{
Thread.Sleep(1000);
if (secondsWaited++ == 10)
{
return false;
}
}
return true;
}
Then each method would do:
runtime.DoSomething();
return WaitReferenceEqualsValue<someType>(ref someField, someSuccessfulValue);
However, when I replace the wait-loop with this method call, the field "connected", even though passed in as a reference, always stays the same.
Any idea what's going on here, and how to get the desired functionality?
Thanks in advance.
EDIT:
public static bool Connect()
{
...
runtime.Connect();
// this code works
/*int secondsWaited = 0;
while (connected != true)
{
Thread.Sleep(1000);
if (secondsWaited++ == 10)
{
return false;
}
}*/
// this somehow blocks OnConnect from firing, so connected never gets set to true
lock (typeof(SkypeKitManager))
{
WaitReferenceEqualsValue<bool>(ref connected, true);
}
...
}
OnConnect:
private static void OnConnect(object sender, Events.OnConnectArgs e)
{
if (e != null && e.success)
{
lock (typeof(Manager))
{
connected = true;
}
}
}
You're not doing any synchronization on that field although you access it from multiple threads and one of them is writing. This is a race (no exception! this is a race even if it looks safe. It isn't safe.).
Probably the JIT enregistered it which is a common optimization. It just never gets read from memory, always from a register. Add synchronization (for example a lock, or Interlocked or Volatile methods).
Your usage of ref is correct.
The problem with your code is essentially compiler optimization. Fo optimization purpose compilers (or jits) necessarily take a pretty much single threaded view. The compiler/jit will then notice that you don't touch reference in your code at all, therefore it can move the comparison outside the loop. It is free to do so, since you basically create a race condition (no synchronization/atomic accesses).
Fixing it could either involve using synchronization mechanisms or add the volatile specifier to reference, thus telling the compiler/jit, that the variable can be changed from outside the method.
In short, I'm utilizing C# to scientific computation and I've written a method that has a while loop that may run to a user-specified quantity of steps... Actually, this method may take too long to execute (like more than 5 hours). When it takes this long, I may want to stop the method pressing Esc key, for example.
As I read something about breaking while, it is as simple as a Boolean flag or something like this. So I thought in something like this:
public Double? Run(int n)
{
int i = 0;
while ((i < n) && (/* inputkey != ConsoleKey.Escape */))
{
// here goes the heavy computation thing
// and I need to read some "inputkey" as well to break this loop
i++;
}
// I'm not worried about the return statement, as it is easy to do...
// returns null if the user skipped the method by pressing Escape
// returns null if the method didn't converged
// returns the double value that the method calculated otherwise
}
Well, this is what I wondered until now... So please, could you give useful ideas to this extent? How can I wait for a user input (I thought about Events, but I'm not sure how to implement it here and I think that it will make the code even slower, if I have to listen to a key at every while step the code goes into...
Well, any ideas or comments?
Update: I think I should have had described better the problem. All the solutions you gave me may solve this problem I proposed, but I think I was not completely reliable to my real problem. I don't know if I should ask another question or keep with this one...
You could run this method from a separate thread and set a stop variable when a key is pressed:
object myLock = new object();
bool stopProcessing = false;
public Double? Run(int n)
{
int i = 0;
while (i < n)
{
lock(myLock)
{
if(stopProcessing)
break;
}
// here goes the heavy computation thing
// and I need to read some "inputkey" as well to break this loop
i++;
}
}
and when a key is pressed, update stopProcessing accordingly:
Console.ReadKey();
lock(myLock)
{
stopProcessing = true;
}
If you're just wanting to stop the application, Ctrl-C from the command line will do it. If you really need to intercept input during a long running process, you might want to spawn a worker thread to do the long running process and then just use the main thread to interact with the console (i.e. Console.ReadLine()).
You will need to do this using threading. When you start the task, spawn a new thread and execute the task on that thread. Then in your Program.cs, wait for user input. If the user enters something meaningful - in your case, the Esc key - alert the background thread of the action. The simplest way to do this is by setting a static variable. The background thread will be checking this static variable and when it has been changed, the background thread will clean itself up and abort.
See the MSDN article on Threading.
A code sample will be a little more in depth, but it would look something like this:
public class Program.cs
{
public static myFlag = false;
public void Main()
{
thread = new Thread(new ThreadStart(DoWork));
thread.Start();
Console.ReadLine();
myFlag = true;
}
public static DoWork()
{
while(myFlag == false)
{
DoMoreWork();
}
CleanUp()
}
public static DoMoreWork() { }
public static CleanUp() { }
}
pool on Console.KeyAvailable in timely manner and take the action accordingly.
using System;
using System.Threading.Tasks;
namespace ConsoleApplication4
{
class Program
{
static bool _cancelled = false;
static void Main( string[] args )
{
var computationTask = Task.Factory.StartNew(PerformIncredibleComputation);
var acceptCancelKey = Task.Factory.StartNew(AcceptCancel);
while (!acceptCancelKey.IsCompleted && ! computationTask.IsCompleted)
{
computationTask.Wait (100);
}
if( acceptCancelKey.IsCompleted && !computationTask.IsCompleted )
{
computationTask.Wait (new System.Threading.CancellationToken ());
}
else if(!acceptCancelKey.IsCompleted)
{
acceptCancelKey.Wait(new System.Threading.CancellationToken());
}
}
private static void PerformIncredibleComputation()
{
Console.WriteLine("Performing computation.");
int ticks = Environment.TickCount;
int diff = Environment.TickCount - ticks;
while (!_cancelled && diff < 10000)
{
//computing
}
Console.WriteLine("Computation finished");
}
private static void AcceptCancel()
{
var key = Console.ReadKey(true);
Console.WriteLine("Press Esc to cancel");
while(key.Key != ConsoleKey.Escape)
{
key = Console.ReadKey(true);
}
_cancelled = true;
Console.Write("Computation was cancelled");
}
}
}