Creating a Loop to Pause a Script While a Callback Function Operates - c#

I am currently using a third party component to handle telnet connections in .NET. I want it to be synchronous where I send a command to the receiving telnet server and then I get the response back as text or byte array. Only problem is that the component is not set up to do that. The component allows me to send commands to the server, but the response is returned via a function handle. So in essence, I need a way to pause the application while the handler does it's processing. Here is an example of how I plan to get around that issue:
static void Main(string[] args)
{
Telnet telCon = new Telnet();
telCon.OnDataIn += new Telnet.OnDataInHandler(HandleDataIn);
telCon.Connect(remoteHostStr);
while (true) ;
}
public static void HandleDataIn(object sender, TelnetDataInEventArgs e)
{
string responseStr = e.Text;
if (responseStr.Contains("Username:"))
{
((Telnet)sender).Send(System.Text.ASCIIEncoding.ASCII.GetBytes(username));
}
else if (responseStr.Contains("Password:"))
{
((Telnet)sender).Send(System.Text.ASCIIEncoding.ASCII.GetBytes(password));
}
}
The solution above will not work since the while will always run, but I will probably build a future version that uses some sort of global variable to track if the loop still needs to run. However, everything I have been taught about programming says this is very dirty. Can anyone think of another way around my dilemma?
Thanks,
Chris

Here is an example of using a ManualResetEvent to suspend execution (and delay program end) until your event handler says it's finished.
static ManualResetEvent finishGate;
static void Main(string[] args)
{
finishGate = new ManualResetEvent(false); // initial state unsignaled
Telnet telCon = new Telnet();
telCon.OnDataIn += new Telnet.OnDataInHandler(HandleDataIn);
telCon.Connect(remoteHostStr);
finishGate.WaitOne(); // waits until the gate is signaled
}
public static void HandleDataIn(object sender, TelnetDataInEventArgs e)
{
// handle event
if (processingComplete)
finishGate.Set(); // signals the gate
}
The WaitOne() method of ManualResetEvent also includes overrides that accept a timespan or number of milliseconds. It returns bool - true if it was signaled, false if it timed out. If you put that in a loop, you could have your main thread wake up every 30 seconds and perform some housekeeping tasks, but still have an instantaneous response when the gate is signaled.

Your while loop:
while(true) ;
will drive CPU usage to 100% (well, 100% of 1 core on a multicore machine) and leave it there, permanently.
This will starve other processes of CPU power, and may prevent the Telnet component from working at all because you've bypassed the message pump.
There are better ways, but without more information on what you're doing, it will be hard to advise you.
To begin, do you want a WindowsForms/WPF/Console application?
[And please, use comments to answer, not Answers.]

In general, when you really need to wait, use a WaitHandle. In this case, a ManualResetEvent would probably be what you need.

A better way would be to spawn the Telnet processing to another thread. That way you can get the main thread to wait for the telnet processing to complete.
Have a look here for some very good tutorials on threading.

Related

What is the reason for "while(true) { Thread.Sleep }"?

I sometimes encounter code in the following form:
while (true) {
//do something
Thread.Sleep(1000);
}
I was wondering if this is considered good or bad practice and if there are any alternatives.
Usually I "find" such code in the main-function of services.
I recently saw code in the "Run" function in a windows azure worker role which had the following form:
ClassXYZ xyz = new ClassXYZ(); //ClassXYZ creates separate Threads which execute code
while (true) {
Thread.Sleep(1000);
}
I assume there are better ways to prevent a service (or azure worker role) from exiting.
Does anyone have a suggestion for me?
Well when you do that with Thread.Sleep(1000), your processor wastes a tiny amount of time to wake up and do nothing.
You could do something similar with CancelationTokenSource.
When you call WaitOne(), it will wait until it receives a signal.
CancellationTokenSource cancelSource = new CancellationTokenSource();
public override void Run()
{
//do stuff
cancelSource.Token.WaitHandle.WaitOne();
}
public override void OnStop()
{
cancelSource.Cancel();
}
This will keep the Run() method from exiting without wasting your CPU time on busy waiting.
An alternative approach may be using an AutoResetEvent and instantiate it signaled by default.
public class Program
{
public static readonly AutoResetEvent ResetEvent = new AutoResetEvent(true);
public static void Main(string[] args)
{
Task.Factory.StartNew
(
() =>
{
// Imagine sleep is a long task which ends in 10 seconds
Thread.Sleep(10000);
// We release the whole AutoResetEvent
ResetEvent.Set();
}
);
// Once other thread sets the AutoResetEvent, the program ends
ResetEvent.WaitOne();
}
}
Is the so-called while(true) a bad practice?
Well, in fact, a literal true as while loop condition may be considered a bad practice, since it's an unbrekeable loop: I would always use a variable condition which may result in true or false.
When I would use a while loop or something like the AutoResetEvent approach?
When to use while loop...
...when you need to execute code while waiting the program to end.
When to use AutoResetEvent approach...
...when you just need to hold the main thread in order to prevent the program to end, but such main thread just needs to wait until some other thread requests a program exit.
If you see code like this...
while (true)
{
//do something
Thread.Sleep(1000);
}
It's most likely using Sleep() as a means of waiting for some event to occur — something like user input/interaction, a change in the file system (such as a file being created or modified in a folder, network or device event, etc. That would suggest using more appropriate tools:
If the code is waiting for a change in the file system, use a FileSystemWatcher.
If the code is waiting for a thread or process to complete, or a network event to occur, use the appropriate synchronization primitive and WaitOne(), WaitAny() or WaitAll() as appropriate. If you use an overload with a timeout in a loop, it gives you cancelability as well.
But without knowing the actual context, it's rather hard to say categorically that it's either good, bad or indifferent. If you've got a daemon running that has to poll on a regular basis (say an NTP client), a loop like that would make perfect sense (though the daemon would need some logic to monitor for shutdown events occuring.) And even with something like that, you could replace it with a scheduled task: a different, but not necessarily better, design.
If you use while(true) you have no programmatic means of ending the loop from outside the loop.
I'd prefer, at least, a while(mySingletonValue) which would allow us to switch the loop as needed.
An additional approach would be to remove the functional behavior from the looping behavior. Your loop my still be infinite but it calls a function defined elsewhere. Therefore the looping behavior is completely isolated to what is being executed by the loop:
while(GetMySingletonValue())
{
someFunction();
}
In this way your singleton controls the looping behavior entirely.
There are better ways to keep the Azure Service and exit when needed.
Refer:
http://magnusmartensson.com/howto-wait-in-a-workerrole-using-system-timers-timer-and-system-threading-eventwaithandle-over-system-threading-thread-sleep
http://blogs.lessthandot.com/index.php/DesktopDev/MSTech/azure-worker-role-exiting-safely/
It really depends on that //do something on how it determines when to break out of the loop.
In general terms, more appropriate way to do it is to use some synchronization primitive (like ManualResetEvent) to wait on, and the code that processes and triggers the break of the loop (on the other thread) to signal on that primitive. This way you don't have thread wasting resources by being scheduled in every second to do nothing, and is a much cleaner way to do it.
I personally don't like Thread.Sleep code. Because it locks the main thread. You can write something like this, if it is a windows application besides it allows you more flexibility and you can call it async:
bool switchControl = true;
while (switchControl) {
//do something
await Wait(1);
}
async void Wait(int Seconds)
{
DateTime Tthen = DateTime.Now;
do
{
Application.DoEvents(); //Or something else or leave empty;
} while (Tthen.AddSeconds(Seconds) > DateTime.Now);
}

Kill thread-based logging instance ungracefully?

Application logging is done using plain and boring log files via a custom rolling flat file logging library. To lower the amount of write accesses to the hard disk, logging events get queued for either when a) a maximum queue item limit is reached or b) a certain amount of time has passed. For the time interval aspect, the logging library runs a thread which flushes the queue periodically.
Now, the logging instance is statically accessible, singleton and application wide (used in many other libraries) and sometimes it happens (altough it shouldn't) that a developer forgets to dispose the flushing thread with the result that, even if the application is 'closed', the thread keeps running and the application has to be killed via a task-manager, which is far from ideal.
So I'm wondering: Is there a possibility to automatically close the thread on application exit? I know about BackgroundWorker, Timer and Threadpool, but are those good solutions for that certain task? Or better stick with the 'classic' Thread?
Detecting that an application is about to exit is very specific to what kind of application you're running.
I don't know much about Aspx, but in WPF you could use the following code to hook up the Exit event of the System.Windows.Application class and close your thread gracefully in the event handler.
Also, you should always avoid killing a thread instead of shutting down gracefully, when it's possible, it can lead to inconsistencies because you have no way of controlling when it will really exit. Instead, you should periodically check for an exit condition, like in the code below.
public static class MyLogger
{
public static void Initialize()
{
if(IsWPFApplication())
Application.Current.Exit += Application_Exit;
//start flush thread and other initializations...
}
private static bool IsWPFApplication()
{
Dispatcher dispatcher = Dispatcher.FromThread(Thread.CurrentThread);
return (dispatcher != null);
}
private static void Application_Exit(Object sender, EventArgs e)
{
Shutdown();
}
private static void Shutdown()
{
ExitRequested = true;
}
}
You can use System.Diagnostic.Process.GetCurrentProcess.Kill though if you are using dot net 4.0 I would recommend using tasks. Here is an excellent resource that I would recommend http://www.albahari.com/threading/.

C# waiting for input from another thread using AutoResetEvent

I spent some time searching for an answer to this and found plenty of helpful information in other threads. I believe I've written the code in a way that works, but I am not happy with the outcome.
I designed a piece of hardware that I am communicating with via C#. The hardware connects via USB and runs initialization routines after enumerating with the OS. At that point, it simply waits for the C# program to start sending commands. In my C# code, the user must press a "Connect" button, which sends a command and the required payload to let the hardware know it should continue running. The hardware then sends a command back as an ACK. The problem is that my C# program must wait to receive the ACK, but the GUI is totally frozen until the hardware responds as I don't know how to partition it out to another thread that can block freely. If the hardware responds immediately, then it works fine, but if it can't connect, then the program stays frozen indefinitely.
With that said, I know a few things need to happen, but I'm not sure how to implement them. First and foremost, I don't think sitting in a loop waiting on a boolean is the right way to go, but using AutoResetEvent doesn't really seem to be much better. There has to be a better way involving timers, more threads, or something similar.
I am using the DataReceived event with the serialPort object as follows:
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
byte cmd = (byte)serialPort1.ReadByte();
if (cmd == (byte)Commands.USB_UART_CMD_MCU_CONNECT)
MCU_Connect_Received.Set();
}
In the buttonClick function ("main" thread), the program stops while it waits for the ACK:
//Send the command to signal a connection
Send_Connection_Packet((byte)Commands.USB_UART_CMD_PC_CONNECT);
textBox1.AppendText("-I- Attempting to contact hardware...");
MCU_Connect_Received.WaitOne();
textBox1.AppendText("Success!" + Environment.NewLine);
Ideally, I'd like to know if a timeout expired so I can print "Failed!" instead of "Success!". Not having a timeout also means it will sit there forever, as I mentioned above, until I kill the process. It's possible that it won't find any hardware, but if it does, it should respond in < 1 second, so a timeout of 2 seconds would be more than enough. I tried using Thread.Sleep, but that froze the GUI as well.
I recommend you use the Task class. You can use a TaskCompletionSource to complete the task when the operation completes.
Using the new async support, your code then becomes:
textBox1.AppendText("-I- Attempting to contact hardware...");
await Send_Connection_Packet((byte)Commands.USB_UART_CMD_PC_CONNECT);
textBox1.AppendText("Success!" + Environment.NewLine);
If you don't want to use the Async CTP, then you can call Task.ContinueWith and pass TaskScheduler.FromCurrentSynchronizationContext to schedule the textBox1.AppendText("Success!") line to run on the UI thread.
The async support also includes timers (TaskEx.Delay) and combinators (TaskEx.WhenAny), so you can easily check for timeouts:
textBox1.AppendText("-I- Attempting to contact hardware...");
var commTask = Send_Connection_Packet((byte)Commands.USB_UART_CMD_PC_CONNECT);
var timeoutTask = TaskEx.Delay(1000);
var completedTask = TaskEx.WhenAny(commTask, timeoutTask);
if (completedTask == commTask)
textBox1.AppendText("Success!" + Environment.NewLine);
else
textBox1.AppendText("Timeout :(" + Environment.NewLine);
The issue with the GUI freezing is because all the callbacks for GUI events occur in the thread that's running the GUI. If you don't want the GUI to freeze you need to spawn a new thread.
For implementing the timeout, you can do a timed wait on an event handle and then check the return value for true or false to determine if the call was successful or if it timed out.
To enable timeouts use another overload of WaitOne():
bool succeeded = MCU_Connect_Received.WaitOne(timeOutInMilliseconds, false);
if (succeeded)
{
textBox1.AppendText("Success!" + Environment.NewLine);
}
else
{
textBox1.AppendText("Failed!" + Environment.NewLine);
}
Consider moving communication-related code in a separate class to encapsulate the communication protocol. This way the code will be easier to maintain and you will able to implement all Task/background worker ideas the other people suggested.
If you want the GUI to remain responsive, you should run things in a background thread. A BackgroundWorker does this nicely. I'd stick with the resetevent over a busy wait construction. You can use a timer to trigger the resetevent after a timeout period

How do I break a loop that is running in different thread using a TimerCallback in C#?

I am writing a game server that has a time limit. I will be accepting input accross a socket until the timer is done. I am using a forever loop to receive data from the client.
while(true)
{
socket.Receive(buffer);
}
I need to break out of this loop when the time limit ends.
Sorry I don't think I am being specific enough.
I have two players sending and receiving data asynchronously. The timer is used to keep track of the time for both players. I need to end the reception of data from both players and give back statistics about their game at the end of the timer.
The best way to handle this is for the thead with the timer to call a stop method in the class where the socket receive method is. This class will have a AutoResetEvent member instance and in the while for the socket read check the event to see if you need to stop:
public class SomeClass {
AutoResetEvent _stopEvent = new AutoResetEvent(false);
Socket _socket;
public void StopReceive() {
_stopEvent.Set();
}
private void SomeMethod() {
_socket.ReceiveTimeout = 5000; // In milliseconds
while(!_stopEvent.WaitOne(0)){
_socket.Receive(buffer);
}
}
}
Edit:
If you have two sockets for the two players on two different threads, with the third thread handling the timeout then the code in all three threads need access to the same event, and change the event to a ManualResetEvent. What I am not sure about is if you have one class that handles the timer thread, and another class that handles the socket read threads for the two players, or if they are handled by one class. If they are separate classes then for the above code you could pass the event in the constructor:
public class SomeClass {
ManualResetEvent _stopEvent;
Socket _socket;
public SomeClass(ManualResetEvent stopEvent) {
_stopEvent = stopEvent;
}
private void SomeMethod() {
_socket.ReceiveTimeout = 5000; // In milliseconds
while(!_stopEvent.WaitOne(0)){
_socket.Receive(buffer);
}
}
}
The timer thread could now call the Set() method in the ManualResetEvent instance and both while loops would terminate.
Have a watchdog timer close the socket when timeout expires. It will cause a SocketException on your socket.Receive call so be prepared to catch it. I use the same mechanism for different purposes.
Solution 2: http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.receivetimeout.aspx but I don't know if it can be applied to your case.
Or, else, you might query the Available property of the socket that indicates how many bytes are ready to be read. But this involves a polling/spinlock, which is bad for performance. Even if you wanted to use a semaphore, which gives you the opportunity to set a maximum timeout, you still need "somebody" to release it when data is available
I was Thinking that instead of creating an infinite loop. I could possibly use a non-blocking socket.
while(stillTime)
{
if(socket.Available > 0)
socket.Recieve(buffer);
}
And when timer goes off set stillTime to false.
Is this a better solution?

How to unblock ConnectNamedPipe and ReadFile? [C#]

I have a class (NamedPipeManager) which has a thread (PipeThread) that waits for a NamedPipe connection using (ConnectNamedPipe) and then reads (ReadFile) - these are blocking calls (not-overlapped) - however there comes a point when I want to unblock them - for example when the calling class tries to stop the NamedPipeManager...
How can I interupt it? Using Thread.abort? Thread.interrupt? Is there a proper way to handle this?
Refer to the code below which illustrates my current situation
main()
{
NamedPipeManager np = new NamedPipeManager();
... do stuff ...
... do stuff ...
np.Stop(); // at this point I want to stop waiting on a connection
}
class NamedPipeManager
{
private Thread PipeThread;
public NamedPipeManager
{
PipeThread = new Thread(new ThreadStart(ManagePipes));
PipeThread.IsBackground = true;
PipeThread.Name = "NamedPipe Manager";
PipeThread.Start();
}
private void ManagePipes()
{
handle = CreateNamedPipe(..., PIPE_WAIT, ...);
ConnectNamedPipe(handle, null); // this is the BLOCKING call waiting for client connection
ReadFile(....); // this is the BLOCKING call to readfile after a connection has been established
}
public void Stop()
{
/// This is where I need to do my magic
/// But somehow I need to stop PipeThread
PipeThread.abort(); //?? my gut tells me this is bad
}
};
So, in function Stop() - how would I gracefully unblock the call to ConnectNamedPipe(...) or ReadFile(...)?
Any help would be appreciated.
Thanks,
It seems to be working on VC6.0, WinXP if I try to interrupt ConnectNamedPipe by
DeleteFile("\\\\.\\pipe\\yourpipehere");
So just specify name, not handle.
Starting with Windows Vista, there is a CancelSynchronousIO operation available for threads. I don't think there is a C# wrapper for it, so you would need to use PInvoke to call it.
Before Vista, there isn't really a way to perform such an operation gracefully. I would advise against using thread cancellation (which might work, but doesn't qualify as graceful). Your best approach is to use overlapped IO.
Recently I was in a situation, I could not use the Async Overlapped IO. I was stuck on the server side within ConnectNamedPipe. To unlock the thread and free resources, I had to connect to the same pipe as a client for a split second.
Main thread receives the stop signal
Main thread sets the stop event for the listening thread
Main thread connects to the pipe
If succeeded (always) - closes the newly created handle immediately
Listener thread unlocks
Listener thread does whatever required
This worked for me very well.
To unblock ReadFile one needs to connect and write to the pipe. Same effect epected.

Categories