I have a multi-threaded C# WPF application that is a plug-in to a larger software (Princeton Instruments LightField, for those who are interested).
My plug-in invokes a synchronous method on a thread separate from the GUI. This method is from a camera API and captures an n-second exposure from the camera and returns the frame that was captured.
The situation looks something like this:
private static volatile bool _STOP = true;
// Runs when the "Run" button is clicked
private void Run_Click(object sender, RoutedEventArgs e)
{
object time = InputTime.Text; // a non-negative integer provided by the user
_STOP = false;
Thread run_thread = new Thread(Running);
run_thread.Start(time);
}
// Runs when the "Stop" button is clicked
private void Stop_Click(object sender, RoutedEventArgs e)
{
_STOP = true;
}
// Separate Thread from GUI
private void Running(object t)
{
int time = Convert.ToInt32(t);
FrameObject f;
while(!_STOP)
{
// synchronously capture a t-second exposure
f = CameraAPI.CaptureImage(t);
// display the exposure on a viewer controlled by the parent thread
Application.Current.Dispatcher.BeginInvoke(new Action(Viewer.Display(f));
}
}
This code (or, rather, it's more complex sibling) works perfectly fine on the computer I developed it on (Computer A). I click Run and the entire application remains responsive while the code is running.
When I try to run it on the computer where it will be hosted regularly (Computer B), however, the following behavior appears:
When clicking the Run button, the GUI becomes unresponsive for n
seconds (n being the time sent to the CameraAPI.CaptureImage(n);
method). This occurs for any positive integer n and continues as the
while loop executes this method each loop cycle (i.e. the application freezes for n seconds, there is a brief unfrozen moment while the Display method is called, and then the application freezes again for n seconds).
If I call Thread.Sleep(n); in place of
CameraAPI.CaptureImage(n);, the application does not freeze.
It is not just my plug-in that freezes - it is the entire application.
I have built, rebuilt, deleted and recopied my code from Computer A to Computer B, and the error persists.
Computer A (where I built this) is identical (as far as I've found)
to the computer having the issues (Computer B). The processors, OS,
drives, RAM, application versions, etc. are all the same. Computer A
specifically exists so that applications can be developed for
Computer B.
Removing the Application.Current.Dispatcher.BeginInvoke(new Action(Viewer.Display(f)); line does not stop the GUI freezing. This is not the problem method.
The application uses the same number of threads (43) on each computer. When the plug-in is running, the number of threads increments by the same amount (1-4 depending on where in the program we are) on each computer.
So, on two seemingly identical systems, the same code has different results. On System A, it works as intended (no GUI freezing), and on System B, the GUI of the entire application -- not just of the plug-in that I am writing -- freezes each time a synchronous method is called.
This error behavior exceeds my understanding of computers, so now I'm here. Any ideas as to what is causing this difference in behavior?
We reinstalled the parent application and everything works fine. Still have no idea why this happened, but closing the question since the problem is resolved. A true case of "turn it off and back on again."
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'm developing an app which basically performs some tasks on timer tick (in this case - searching for beacons) and sends results to the server. My goal was to create an app which does its job constantly in the background. Fortunately, I'm using logging all over the code, so when we started to test it we found that sometime later the timer's callback wasn't being called on time. There were some pauses which obviously had been caused by standby and doze mode. At that moment I was using a background service and System.Threading.Timer. Then, after some research, I rewrote the services to use Alarm Manager + Wake locks, but the pauses were still there. The next try was to make the service foreground and use it with a Handler to post delayed tasks and everything seemed to be fine while the device was connected to the computer. When the device is not connected to a charger those pauses are here again. The interesting thing is that we cannot actually predict this behavior. Sometimes it works perfectly fine and sometimes not. And this is really strange because the code to schedule it is pretty simple and straightforward:
...
private int scanThreadsCount = 0;
private Android.OS.Handler handler = new Android.OS.Handler();
private bool LocationInProgress
{
get { return Interlocked.CompareExchange(ref scanThreadsCount, 0, 0) != 0; }
}
public void ForceLocation()
{
if (!LocationInProgress) DoLocation();
}
private async void DoLocation()
{
Interlocked.Increment(ref scanThreadsCount);
Logger.Debug("Location is started");
try
{
// Location...
}
catch (Exception e)
{
Logger.Error(e, "Location cannot be performed due to an unexpected error");
}
finally
{
if (LocationInterval > 0)
{
# It's here. The location interval is 60 seconds
# and the service is running in the foreground!
# But in the screenshot we can see the delay which
# sometimes reaches 10 minutes or even more
handler.PostDelayed(ForceLocation, LocationInterval * 1000);
}
Logger.Debug("Location has been finished");
Interlocked.Decrement(ref scanThreadsCount);
}
}
...
Actually it can be ok, but I need that service to do its job strictly on time, but the callback is being called with a few seconds delay or a few minutes and that's not acceptable.
The Android documentation says that foreground services are not restricted by standby and doze mode, but I cannot really find the cause of that strange behavior. Why is the callback not being called on time? Where do these 10 minutes pauses come from? It's pretty frustrating because I cannot move further unless I have the robust basis. Does anybody know the reason of such a strange behavior or any suggestions how I can achieve the callback to be executed on time?
P.S. The current version of the app is here. I know, it's quite boring trying to figure out what is wrong with one's code, but there are only 3 files which have to do with that problem:
~/Services/BeaconService.cs
~/Services/BeaconServiceScanFunctionality.cs
~/Services/BeaconServiceSyncFunctionality.cs
The project was provided for those who would probably want to try it in action and figure it out by themselves.
Any help will be appreciated!
Thanks in advance
I have an app that has a BG module which is forced to run at every 4 mins for testing purpose, and it works fine. Once I launch the app(first launch) and register with the server the contents are displayed and I exit the app. The app goes to Application_Closing() state. I wait for a while(say about 15 mins) and try to launch the app, sometimes it so happens that, after the MainPage() constructor is executed, the app gets deactivated and while debugging and from the logs I observed that the app goes to Application_Deactivated() state.Basically, the app launches, its still displaying the Splash Screen(Customized) and it terminates all of a sudden. So, after I went through the log there is one question that is bothering me, i.e., if an app is launched while still the BG task is doing its job, and there is a conflict between the FG and the BG task will that in anyway result in Application Deactivation? I also have doubt that I must be doing something more inside the Application_Deactivated() method in the APp.xaml.cs class. Here is the Code.
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
Logger.log(TAG, "Application deactivated");
}
// Code to execute when the application is closing (eg, user hit Back)
// This code will not execute when the application is deactivated
private void Application_Closing(object sender, ClosingEventArgs e)
{
if (appSession != null)
{
appSession.close();
}
Logger.log(TAG, "Application closed");
}
//Log:-
From what I understand from your query, I can conclude that since the Application is running in the BG thread before it is launched, its unable to allocate UI resources which require it to be on the FG (which is not happening due to the cross threading issue). I guess you need to sort out this conflict before you proceed.
Note: I am not sure about this. Its only an observation. Hope my answer helps you.
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.