My program runs a test over a serial connection. After I click the RUN TEST button everything works great. The RUN TEST button disappears and the STOP button pops up. Data collection runs as expected. My problem is that the STOP button doesn't respond. All of my testing code is run under the RUN TEST button click event. Is this uninterruptible by my second button?
Note: I use the whateverButton.enable and whateverButton.visible properties. Is there another one I need to set to get this to work?
runButton.Enabled = false;
runButton.Visible = false;
STOPbutton.Enabled = true;
STOPbutton.Visible = true;
The rest of the program is to big to fully include.
Any help with this would greatly appreciated.
Let me guess - you disable the "Run", enable the "Stop", perform your task, reverse the enable/disable on "Run" and "Stop"?
Your issue is that the UI is not updated because the UI thread is busy running your task.
Use BackgroundWorker or Task.Run to spawn a new thread for the task, some significant refactoring may need to happen to take UI interaction out of the background thread and to support cancelling.
Related
I have a list of tasks running and would like to show the progress in a (WinForms) form with a Cancel button.
I am aware, that there are several async options, but I have two restraints: The tasks must not run on a separate thread and the solution must be compatible with .NET 3.5 (it is an AddIn for a program, I have no access to).
It is fine, if one task finishes, before the cancellation comes into force. So I wonder, if there is some chance to check in synchronous code, if a mouse click on a button happened while having performed some task?
edit: This is the intended code:
foreach (IStep step in Steps)
{
if (Cancelled)
return;
step.Run();
ReportProgress(100.0 * completedWeight / totalWeight, step.Description);
completedWeight += step.Weight;
}
ReportProgress(100, "Completed");
So IStep contains a Run() method, and I am perfectly fine with completing a step before cancelling. I do not know how to catch mouse click on the Cancel button while executing some step to set Cancelled to true.
Obviously there is no "standard" solution here, so we have to think outside the box...
Say you have your application (AddIn or whatever, doesn't matter) and you can't control the loop from a button.
You read/write to the database.
On top of your loop, where it says:
if (Cancelled)
return;
We have to replace with:
If(CheckIsCancelled())
You have to find a way to make a button that can be clicked, either another form near the current one, but it must be able to run independently from the current form that is blocked by your loop.
Create a database parameter in some sort of Config/Util table.
E.g. CancelMyLoop - Bit
On that button click - set the parameter value to true.
And back to the method: CheckIsCancelled()
it will go in the db and read that value every time.
Downside is performance, but you want the impossible so you have to settle with a workaround like this...
You can create your own implementation, just giving you an idea.
I have my code and problem like below
step1.Visible = true;
//step1 is visible if i retrun from here but if do some work like below than its not visible until the task is completed
Thread.Sleep(5000); // some opration here Thread.Sleep is just for example
step1.Visible = true;// step1 visible here not before thread going to sleep
Here I want to show the image for each step but first step image not showing if it's followed by some long running task any idea/trick show step1 in the case of Thread.Sleep(5000)?
Use Application.DoEvents() before your Sleep (Any long running) Code.
Application.DoEvents() will processes all Windows messages currently in the message queue.
step1.Visible = true;
// Below 3 lines are not necessary. Use it only if DoEvents() doesn't work.
//step1.Invalidate();
//step1.Update();
//step1.Refresh();
// Will process the pending request of step1.Visible=true;
Application.DoEvents();
Thread.Sleep(5000);
step1.Visible = true;
I'm not sure if I understand what do you want to do but first I will use those two function : Show() and Hide()
Now you have to work with Multi Threading and comunication between Threads
Hope this could help
You should use delegates or backgroundworker process to achieve that. you can get and idea from the link below.
Animated GIF in Windows Form while executing long process
Thanks
I have 2 windows. The main form and the Loading form. In the main form you send a request which will be executed. Because this takes some time, I made the Loading-form with a progress bar so that the user knows the program is working.
What I want to: The Loading-form should open itself when the process ist started and close itself when it's finished.
At the moment I have code that looks something like this:
Loading.Show();
Loading.MakeAStep(); //used for progressing the progress bar
//program is working
//finishes
Loading.Visible = false;
Loading.ResetProgress(); //Sets the value of the progress bar to 0
My problem is: The window with the progress bar opens, but there is also a label which shows "please wait". When the form opens, the progress bar works perfectly, but the label is just a hole (it really is you can look through it). When I use instead of visible = false form.Close, it works just fine with the label but I get an error when I try to start a progress in the same session.
What I want/need: Either a solution to the hole-problem, or an effective way to open and close a form several times during one session.
(Posted the solution on behalf of the question author).
The answer is in the comments: The UI blocks and I needed to Update the form with Loading.Update(); I put that between Show and MakeAStep.
As already mentioned by others, the problem is that you run your long running process in the UI thread. To avoid this, you should improve how the loading form receives the task and works on it:
The loading form should get the thing to run as a Task (maybe by a method Run(Task task). After getting this task the loading form can attach another action to it, what shall happen when the task is finished by using .ContinueWith() and simply closes itself when it reaches that point. After that it will Start() the task and call ShowDialog() on itself.
Pretty new to DevExpress, my company is stuck using 9.3
I've got this very small snippet of code:
wait = new DevExpress.Utils.WaitDialogForm("Please wait...", "Performing SVN check");
wait.Visible = false;
wait.ShowDialog();
ParseSVNResults(CheckSVN());
wait.Close();
My WaitDialog displays, but the code never continues. I put a breakpoint on ParseSVNResults and when I run the code it gets to that line.
It works properly if I just call Show() instead of ShowDialog(), but that gives poor behavior should the user click outside of the Wait form. The application "whites out" like it's stopped responding and the mouse changes into that little rotating circle icon. Also the hour glass that the dialog form shows doesn't rotate. Stupid minor detail, but it looks like the whole application crashed to end users.
ShowDialog, by design, "blocks" the code until you close the dialog. That is the entire purpose.
The reason that Show() is causing everything to white out is that your work is happening in the UI thread. The proper way to handle this would be to move your work (ParseSVNResults) into a background thread, via something like BackgroundWorker or a Task.
I have strange issue reported by users and once reproduced by me.
I have form with various buttons and each button performs long operation.
When new buttons are clicked old operation will stops and new will be started.
And i noticed strange behaviour:
When i am clicking button sometimes operation doesnot started.
Operation cannot be started because next code:
if (!Worker.IsBusy)
{
RunReload();
}
else
{
isWorkerPendingForNewJob = true;
Worker.CancelAsync();
}
Cancel is called few times but my worker is always busy!
When i brake my project execution i noticed that it stops on lock section.
Inside this lock i am just creating some objects that are used for all processes.
Brackpoints on image never hits.
Why backgroundworked is always busy and locked on this line?
When you call CancelAsync(), it just set the flag CancellationPending to true. You must manually check periodically this flag in your BackgroundWorker work function and interrupt it yourself. Are you doing this already?
Here is the related MSDN page.
Also, you must ensure that WorkerSupportsCancellation is true to support CancelAsync.