I have a tray icon that needs to display two icons:
If there is network connectivity, display a green circle with a check mark
If there isn't network connectivity, display a red circle with an X
So what I have is:
using System.Net.NetworkInformation;
bool isConnected = NetworkInterface.GetIsNetworkAvailable()
So I'm thinking of starting a new thread or using the background worker progress because the tray icon is a NotifyIcon which is a component so I can't use:
Form.Invoke(delegate, object[])
to update the icon property of the NotifyIcon class.
My big concern is the polling process: I could write some logic that does:
while (true)
{
System.Threading.Thread.Sleep(1000);
isConnected = NetworkInterface.GetIsNetworkAvailable();
if (isConnected)
notifyIcon.Icon = "ConnectedIcon.ico";
else
notifyIcon.Icon = "DisconnectedIcon.ico";
}
but I've seen a couple of articles that tell me to stay away from Sleep(1000). I can't seem to find those articles since I didn't bookmark them. I'm just curious to know why that isn't a good idea for polling in a thread.
You can register an Event on NetworkChange so you are being notified when the status changes:
NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged);
void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
{
if (e.IsAvailable) {
Console.WriteLine("Network Available");
} else {
Console.WriteLine("Network Unavailable");
}
}
In you situation its totally fine to use the Sleep method.
What you saw was probably saying so its better to use a Reset Event - from looping etc...
Polling isn't always evil, but it's best avoided if possible. If I run your application that's polling once per second, that means that once per second your program is getting scheduled to do work on a CPU core that is 99.9999% going to be a no-op. On a desktop that's not too terrible, but imagine a laptop. CPUs there try run in very low power modes whenever possible, so additional CPU work means less battery life! This is the reason why many mobile platforms (iOS, Windows Phone 7, etc) ban arbitrary background threads because they know people will abuse them.
In your case, there's an easier way: just use System.Net.NetworkInformation.NetworkChange which provides events for when the network connectivity changes. No polling required!
Related
I'm working on a Windows forms application that needs to perform some logic before the PC goes to sleep. I've looked through many threads and found this which should work perfectly: Link. I can detect when the power is plugged/unplugged just fine, but I've run into serious problems when trying to detect a sleep/suspend event.
Using the logic mentioned, I have this section of code in my program:
public void powerModeChanged(object sender, PowerModeChangedEventArgs args)
{
if (args.Mode == PowerModes.Suspend)
{
Trace.WriteLine("Sleeping.....");
}
else if (args.Mode == PowerModes.StatusChange)
{
Trace.WriteLine("Other Status Change:");
}
}
public MainPage()
{
InitializeComponent();
SystemEvents.PowerModeChanged += new PowerModeChangedEventHandler(powerModeChanged);
Per this documentation page - Link, there are 3 types of power modes. The statusChange is detected as expected when I unplug and replug the power adapter into my laptop, and prints to the debug Window just fine. However, it will not detect when I put the computer to sleep. After going over this for hours, my conclusion is that what the version of Windows 10 I'm running defines as "sleep" doesn't match up with the event that I'm checking for.
There is a comment on that initial thread in the first link that says the solution I tried doesn't seem to work with the "new Connected/Modern Standby modes" and provides a link to this thread: Link where it describes using the session switch event handler instead. This works on my laptop as my laptop locks upon sleep, but when testing on a Surface tablet (which is our target device for operation), it doesn't work due to the surface not locking upon sleep.
Of course, I could just set the device to lock on sleep, and that may end up being the only solution, but I wanted to see if there was something I was overlooking or any other way to check for sleep in modern versions of Windows. As it stands, I would hate for this important feature of the application depend on the system having to be setup to lock when sleeping. Thanks!
You could use the SystemEvents.PowerModeChanged event to detect when the computer is about to go to sleep. Within the event handler, you can perform any logic that needs to be done before the computer goes to sleep. For example, you could write commands to the windows registry or perform some other related tasks.
Below is an example of how this could be done:
// Register the SystemEvents.PowerModeChanged event handler
SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
// Event handler for SystemEvents.PowerModeChanged
private void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
{
// Check if the computer is about to go to sleep
if (e.Mode == PowerModes.Suspend)
{
// Perform the logic that needs to be done before the computer goes to sleep
// ...
}
}
I ended up finding this thread, the answer on that thread solves this issue.
Link to Solution
I am just wondering if it is possible to stop a windows workstation from locking using the SessionSwitch event in a Windows Form.
I am working on a (very simple) time and attendance system, and I want to prevent a user locking their screen unless they have set their status to away/lunch.
Current code is like this.
protected override void OnLoad(EventArgs e)
{
SystemEvents.SessionSwitch += new SessionSwitchEventHandler(SystemEvents_SessionSwitch);
}
void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e)
{
if (e.Reason == SessionSwitchReason.SessionLock)
{
MessageBox.Show("Logout reason " + e.Reason);
// Check if status is valid for logout, if not then prevent lock
}
}
Is there a way to prevent the screen locking from within a windows form? Or should I look for a different solution?
Thanks.
I don't believe you can stop the user from locking the screen. But, even if you can, what good would it be? They can still go away without locking their screen, can't they?
To me, it comes across as if you need to attribute time to a valid category like Lunch, Work, Meeting, etc. If that's the case, you need to realize that you can't force the user to do it. But, you can incentivize the user to do so or punish the user for not doing so.
I might suggest, hooking up to relevant event (SessionSwitch, Applications.Idle) and using a heuristics to guess the category (say if computer is idle for more than 20 minutes then categorize it as Lunch break). Provide the user with the ability to change the categorization. This way folks who have 3 lunch breaks in their timesheet, might start setting the system with the correct category before leaving for a break.
as I am new in multithreaded application I would like to have some advice from more experienced people before starting to write the code...
I need to queue data received on serial port in serial port event for further processing.
So I have the following event handler:
void jmPort_ReceivedEvent(object source, SerialEventArgs e)
{
SetStatusLabel("Iddle...", lbStatus);
SetPicVisibility(ledNotReceiving, true);
SetPicVisibility(ledReceiving, false);
String st = jmPort.ReadLine();
if (st != null)
{
lines.Enqueue(st); //"lines" is the ConcurrentQueue<string> object
StartDataProcessing(lines); //???
SetStatusLabel("Receiving data...", lbStatus);
SetPicVisibility(ledNotReceiving, false);
SetPicVisibility(ledReceiving, true);
}
else
{
jmPort.Close();
jmPort.Open();
}
}
Within the StartDataProcessing I need to dequeue strings and update MANY UI controlls (using the InvokeRequired...this I already know :-)).
What is the best approach and colision free (without deadlock) approach to achieve this?
How to call StartDataProcessing method in more threads and safely dequeue (TryDequeue) the lines queue, make all needed computations and update UI controlls?
I have to appoint that the communication is very fast and that I am not using the standard SerialPort class. If I simply write all received strings without further processing to console window it works just well.
I am working in .NET 4.5.
Thank you for any advice...
Updated question: Ok, so what will be the best way to run the task from the datareceived event using TPL? Is it necessary to create another class (object) that will process data and use callbacks to update UI or it is possible to load some form method from the event? I'll could be very happy if someone can give me the direction what exactly to do within the datareceived event. What to do as the first step because studying all possible ways is not the solution I have time for. I need to begin with some particular way... There is so many different possible multithreading approaches and after reading about them I am still more confused and I don't know what will be the best a fastest solution... Usual Thread(s), BackgroundWorker, TPL, async-await...? :-( Because my application uses .NET 4.5 I would like to use some state-of-the-art solution :-) Thank you for any advice...
So after a lot of trying it is working to my satisfaction now.
Finally I've used the standard .NET SerialPort class as the third-party Serial class causes somae problems with higher baudrates (115200). It uses WinAPI directly so the finall code was mixed - managed and unmanaged. Now, even the standard .NET 4.5 SerialPort class works well (I've let my application successfully running through a whole night).
So, for everyone that need to deal with C#, SerialPort and higher rates (only for clarification - the device sending messages to PC is the STM32F407 /using USART 2/. I've tried it also with Arduino Due and it works as well) my datareceived event is in the following form now:
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
//the SetXXXXX functions are using the .InvokeRequired approach
//because the UI components are updated from another thread than
//the thread they were created in
SetStatusLabel("Iddle...", lbStatus);
SetPicVisibility(Form1.frm.ledNotReceiving, true);
SetPicVisibility(Form1.frm.ledReceiving, false);
String st = serialPort1.ReadLine();
if (st != null)
{
lines.Enqueue(st);
Task.Factory.StartNew(() => StartDataProcessing(lines)); // lines is global ConcurrentQueue object so in fact there is no need to pass it as parameter
SetStatusLabel("Receiving data...", lbStatus);
SetPicVisibility(Form1.frm.ledNotReceiving, false);
SetPicVisibility(Form1.frm.ledReceiving, true);
}
}
Within the StartDataProcessing function:
1. TryDequeue(lines, out str)
2. Use the ThreadPool.QueueUserWorkItem(lCallBack1, tmp); where tmp is needed part of the str (without EOF, without the message number etc.)
lCallBack1 = new WaitCallback(DisplayData);
Within the DisplayData function all the UI controls are updated
This approach mixes the ThreadPool and TPL ways but it is not a problem because the ThreadPool is used by TPL in background operation anyway.
Another working method I've tried was the following:
ThreadPool.QueueUserWorkItem(lCallBack, lines);
instead of :
Task.Factory.StartNew(() => StartDataProcessing(lines));
This method was working well but I've not tested it in over night run.
By my subjective perception the Task.... method updated the controls more smoothly but it can be only my personal feeling :-)
So, I hope this answer will help someone as I know from forums that many people are dealing with with unreliable communication based on the micocontroller <--> PC
My (surprising :-) ) conclusion is that the standard .NET SerialPort is able to handle messages even at higher baudrates. If you still run into troubles with buffer overrun then try to play with the SerialPort buffer size and SerialPort threshold. For me the settings 1024/500 are satisfactory (max size of the message send by microcontroller is 255 bytes so 500 bytes means that 2 messages are in buffer before the event is fired.)
You can also remove all SetXXXX calls from the datareceived event as they are not really needed and they can slow down the communication a little...
I am very close to real-time data capturing now and it is exactly what I've needed.
Good luck to everyone :-)
Within the StartDataProcessing I need to dequeue strings and update MANY UI controlls
No, you do not. You need to dequeue strings and then enqueue them again into the multiple queues for the different segments of the UI.
If you want to be fast, you scatter all operations and definitely the UI into separate windows that run their own separate message pumps and thus can update independently in separate UI threads.
The general process would be:
1 thread handles the serial port and takes the data and queues it.
Another one dequeues it and distributes it to separate processing threads from which
the data goes to multiple output queues all responsible for one part of the UI (depending on whether the UI Will turn a bottleneck).
There is no need to be thread safe in dequeuing. How serial is the data? Can you skip data when another update for the same piece arrives?
Read up on TPL and tasks - there are base libraries for parallel processing which come with a ton of documentation.
This is an odd question, I understand. I also assumed it would be simple, because lord knows I have created my share of infinite loops.
I'm trying to cause a slight PC lag in C# - specifically I need to create a 'choppy mouse' situation system wide (not just the sandboxed exe).
The little app can't crash the computer! The lag should be able to run for 2-10 seconds ish - then stop.
What I have tried so far:
-Spawning numerous threads that save data (filled up memory and cause PF usage, no real lag).
-Spawning TONS of threads (lag at first, but then none when treads are re-spawned again - as if the second time the OS is ready).
-Spawning threads that take several screenshots (the screenshots don't seem to lag).
None of these have worked - any ideas?
Optional back story (optional):
The reason for the application, without divulging any company information, is to cover up a laggy background process in a production environment. We have tried to speed the app up, or improve the computers with no results. There is an abuse case that is present when production workers associate a lag with this background application running. The goal is to disassociate this lag ... by creating a similar one at random times sparingly.
Clarification:
The original background app is not home grown (fyi) the only real solution would to be purchase 1000s of new boxes. The company is going with the cheaper 'hide the background app' ... 'solution'. I know...
You can just create a background app that randomly calls the Windows BlockInput API at a desired interval. This allows your app to have as small a footprint as possible preventing it from taking up CPU cycles and memory.
More information here:
http://msdn.microsoft.com/en-us/library/ms646290.aspx
That said, I agree with the other posts / comments that this is addressing the symptoms and not the problem.
EDIT: code example
using System.Runtime.InteropServices;
using System.Threading;
namespace LagTimer
{
class Program
{
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern bool BlockInput([In, MarshalAs(UnmanagedType.Bool)] bool fBlockIt);
static void Main(string[] args)
{
Thread t = new Thread(LagTick);
t.Start();
while (true) { } // Prevent the app from exiting
}
static void LagTick()
{
while (true)
{
BlockInput(true);
System.Threading.Thread.Sleep(250);
BlockInput(false);
// TODO: Randomize time in between ticks
Thread.Sleep(100);
// TODO: Add logic for when to "sputter" the mouse
}
}
}
}
You could make a thread that has an infinite loop, and every X seconds raises an event that the UI Thread catches. The UI thread could then call Thread.Sleep for however long you want.
PLEASE DON'T DO THIS
That said, it could be accomplished by creating a number of threads that matches the number of logical processor cores in the system, set the processor affinity of each thread so that there's one per core, and then just have each thread run code like this:
int i = rand();
while (!timeLimitExpired())
{
i += rand() % i;
}
The purpose of the rand() call is to keep a compiler optimization from realizing that your loop doesn't actually do anything and optimizing it away, and the purpose of the modulo operation is to prevent creating an overflow (exception) (you could use simple division as well).
Because I don't think you should do, I won't share the code on how to determine the number of processor core or detect thread affinity. Instead, please please please fix your app. It's probably as simple as adding a sleep() call in the middle of a tight loop somewhere.
It sounds like you are trying to make a timed busy-loop. The simplest way to do that is just a tight loop that checks the clock and exits when a certian delta of time has passed.
Now, on a typical PC you might not see any "lag" when this happens. Why? Well there are a couple of reasons.
Multiple CPUs. If you don't do this on every CPU, then there's a free CPU for the OS to use and you might not notice the difference. To make sure you are using every CPU, I'd suggest creating a process to run your "cpu eater" with the CPU affinity set or CPU 0, and then another for each other CPU the system has.
Task priorities. Generally things like the desktop are given a higher priority than background tasks. If you want to keep your program from being pre-empted by that, you need to make it a very high priority.
Note: if you make your task high-priority, and then somehow set it up to run on startup or login, I am not responsible for any damage you do to your machine or OS reinstalls you are forced to perform. Also, chewing up large amounts of CPU for extended periods can cause PCs with stock cooling setups to overheat. This causes crashes and sometimes permanent damage.
I would like to add that, while we developers don't have to sign onto any code of ethics to get professional licenses like Doctors, Lawyers, and some engineers must do, there are still times when we have an obligation to refuse to carry out unethical requests.
Since you say these are your company's own machines that they are looking to slow down, that's stoopid, but not unethical. However, if these were customer machines then I'd have to put my foot down. Your boss won't thank you (and may even fire you), but your company would get absolutely roasted if/when a customer finds out what is really going on. Doing the right thing for both your company and its customers, against supervisor wishes, is what ethics is all about.
You bind a
Form2 Form = new Form2();
// open form2
Form.Show();
to a
private void timer1_Tick(object sender, EventArgs e)
//spam form2. Maybe set timer Interval to 10 or 5.
{
}
And it will lag intense within 4 min or so. atleast I can't access the task manager.
form2 properties, put opacity 0%, windowsstate = Minimized and don't show in taskbar.
this is an example:
private void timer1_Tick(object sender, EventArgs e)
//spam form2. Maybe set timer Interval to 10 or 5.
{
Form2 Form = new Form2();
// open form2
Form.Show();
}
Background
My son likes to use his laptop when he's not supposed to and I just thought it would be handy if I could write an application that would email me whenever he opened / closed his laptop.
(I'd even settle for something that notified me when there was network traffic on the machine)
Question
How do you programmatically detect when an OS is waking up or going to sleep? I found this link from this related post. But that covers OS X. I'm looking for the same thing for Windows 7.
(I'd like to do this in Java, if possible, but I'd settle for C#/C++)
Easiest way is not to write any code at all, even though this is stack overflow. Click Start, type Schedule and choose Scheduled Tasks. Set one up (click Create Task) and set a Trigger when the machine is unlocked. For the Action, have it send you an email.
Repeat for startup and when a user logs in, if you want. Done.
You're going to want to create a window and watch for the WM_POWERBROADCAST message (http://msdn.microsoft.com/en-us/library/aa373248%28v=vs.85%29.aspx) and check the wParam for your desired action. For example, your window should receive a WM_POWERBROADCAST with PBT_APMSUSPEND as the wParam when the system is about to enter a suspended state (i.e. closing a laptop). Resuming seems to have a few different wParam values: PBT_APMRESUMESUSPEND, PBT_APMRESUMECRITICAL and PBT_APMRESUMEAUTOMATIC
I search for a long time and found that this was the best way, the 'Sleep'-event was never working before:
private ManagementEventWatcher managementEventWatcher;
private readonly Dictionary<string, string> powerValues = new Dictionary<string, string>
{
{"4", "Entering Suspend"},
{"7", "Resume from Suspend"},
{"10", "Power Status Change"},
{"11", "OEM Event"},
{"18", "Resume Automatic"}
};
public void InitPowerEvents()
{
var q = new WqlEventQuery();
var scope = new ManagementScope("root\\CIMV2");
q.EventClassName = "Win32_PowerManagementEvent";
managementEventWatcher = new ManagementEventWatcher(scope, q);
managementEventWatcher.EventArrived += PowerEventArrive;
managementEventWatcher.Start();
}
private void PowerEventArrive(object sender, EventArrivedEventArgs e)
{
foreach (PropertyData pd in e.NewEvent.Properties)
{
if (pd == null || pd.Value == null) continue;
var name = powerValues.ContainsKey(pd.Value.ToString())
? powerValues[pd.Value.ToString()]
: pd.Value.ToString();
Console.WriteLine("PowerEvent:"+name);
}
}
public void Stop()
{
managementEventWatcher.Stop();
}
A very simple, perhaps crude, but effective way may be to have a program with a timer firing every minute. If the timer fires and it's been, say, 5 minutes of real time since its last execution then you can likely assume that the computer was sleeping since it's unlikely that your thread was unable to be scheduled for so long.
The other reason for the difference may be a clock adjustment, like DST or a manual change, but that kind of "noise" should be very low, in your scenario.
You could write a simple app and register it as a Windows service, to be started automatically at system startup. This app could then do whatever you want when it starts. And if it's a proper Windows app, it can register to get notification about impending system shutdown too (I don't remember the details but I implemented this in a C++ MFC app many years ago).
If you prefer Java, you could register your app as a service via a suitable service wrapper like Tanuki (it seems they have a free Community License option). Although this might be overkill. And it may be possible to get notification about the JVM shutting down when the system is closing (but I have no concrete experience with this).
http://www.pinvoke.net/default.aspx/powrprof.CallNtPowerInformation - Check out the link. It has almost all win32api for all windows function. You can call power management feature directly in your windows 7 laptop. For that create a Windows Service , that will use these specific api to notify the machine state.