How to cope with the task

In my C # program there is a "Login" function. When the user clicks the button, the program uses the login / logon data to log in to a specific site using the POST URL and save cookies. Then, in my program, the web page is further processed after logging in. Then the result is displayed to the user.

The problem is the moment when the user clicks on the button - the whole program freezes and waits until the operation from above is completed. This is approximately 3-5 seconds of inactivity.

I would like to block user input during this time and request a message, for example, "work ...". Othervise there is no way to say that the program is actually working on something or not. Here is what I mean:

enter image description here

What methods should be used to achieve the desired goal?

+4
source share
4 answers

The UI is blocked because you are using the user interface thread login code. To avoid this, you can use "BackgroundWorker", or if you use 4 or 4.5.NET, you can use "Tasks" to move your stuff to enter another thread to avoid blocking the user interface.

If Windows Forms and .NET 4+ can work the following:

private void button1_Click(object sender, EventArgs e) { progressBar1.Visible = true; Task.Factory.StartNew(Login) .ContinueWith(t => { progressBar1.Visible = false; }, TaskScheduler.FromCurrentSynchronizationContext()); } private static void Login() { // should replace this with actual login stuff Thread.Sleep(TimeSpan.FromSeconds(3)); } 

What he does is he moves the input processing to another thread, so the UI thread is not blocked. Before entering the system, it displays a progress bar, which has the style set in marque, and after Login is finished, it again hides the progress bar.
As long as the user interface is not blocked, the user is allowed to enter / press whatever he wants during login, so the solution will either disable all controls before entering the system or display the progress bar in a separate modal form, so the user will not see the application is hanging and cannot do anything until the execution form is closed.

Update: added example with a separate execution form:

 public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { MarqueeForm.DoWithProgress("Doing login", Login); } private static void Login() { Thread.Sleep(TimeSpan.FromSeconds(3)); } } public class MarqueeForm : Form { private Label label; public MarqueeForm() { var progressBar = new ProgressBar { Style = ProgressBarStyle.Marquee, Top = 20, Size = new Size(300, 15) }; Controls.Add(progressBar); label = new Label(); Controls.Add(label); } public static void DoWithProgress(string title, Action action) { var form = new MarqueeForm { Size = new Size(310, 50), StartPosition = FormStartPosition.CenterParent, FormBorderStyle = FormBorderStyle.FixedDialog, ControlBox = false, label = { Text = title } }; form.Load += (sender, args) => Task.Factory.StartNew(action) .ContinueWith(t => ((Form)sender).Close(), TaskScheduler.FromCurrentSynchronizationContext()); form.Show(); } } 
+3
source

First of all, you need a background worker. There is a simple tutorial on it (with a progress bar) in BackgroundWorker Basics in C #

+4
source

When you click a button, you can disable the button button1.Enable = false; when a message like "Please wait .." is displayed. Turn on the button when the process is completed and the result is displayed.

0
source

I assume this is a Forms application?

If so, you can set your form to a “loading screen”, then execute Application.Doevents (); then run your process. After that, you can delete your “boot screen”.

0
source

Source: https://habr.com/ru/post/1483337/


All Articles