简体   繁体   中英

Multithreading - Button Click Event - On User Control

In my project i have main form. On that Main form i am calling User Control at runtime. the sequence of event running like this.

  1. Scan the Barcode - do some process on this code

  2. Ask User "would you like to scan more?" and then shows "YES/NO" option. this is not popup window, i have to update Message on Screen in my touch screen computer for Kiosk.

  3. Wait for User input for some time.

  4. If user click on "Yes" then Accept other barcode.

  5. If user click on "No" then do further processing.

  6. If user does not reply in timely fashion then do further processing as doing in "No" reply.

Question:

  1. How to visible button in between of thread?

  2. How to handle button click event if in case of user reply.

     void ShowMoreVoucherOption(bool showhide) { if (this.btnYes.InvokeRequired) { this.BeginInvoke((MethodInvoker)(() => btnYes.Visible = showhide)); this.BeginInvoke((MethodInvoker)(() => btnNo.Visible = showhide)); } else { btnYes.Visible = true; btnNo.Visible = true; } Application.DoEvents(); } 

I am calling this routine in between of thread of as below. this is not UI thread.

UpdateProgessLabel("Would you like to add more vouchers?");
ShowMoreVoucherOption(true);
Thread.Sleep(15000);
Dofuthrerporcessing(); // in case user does not give input

now, wait for 15 sec, if user inputs then continue on button click event and if not then continue over here.

I am not sure Thread.sleep in appropriate over here or not. or do i have to use ManualResetEvent and waitone? and how to handle the button click over there?

If you have totally no idea if you are in the UI thread or not (which seems to be the point of this question) then you should create a background thread to do the job for you. The simplest thing would be doing the following:

if(SomeKindOfAFormOrAControl.InvokeRequired) // You are not in the UI Thread
{
  Thread.Sleep(15000);
  UpdateProgessLable("Your message.");
}
else // You are in the UI Thread
{
  ThreadPool.QueueUserWorkItem(delegate {  // Spawn a Background Thread
    Thread.Sleep(15000);
    UpdateProgessLable("Your message.");
  });      
}
//Your UI thread will keep running from this point if
//SomeKindOfAFormOrAControl.InvokeRequired was false.

Is this what you are looking for?

Edit:

In the UI thread, you don't have to call Invoke and you can manipulate UI from there; as a matter of fact you have to call Invoke when you are NOT in the UI thread. So:

If it is the UI Thread that needs to hide buttons after 15 seconds, you have to run it in a background thread as I did in the code above:

ThreadPool.QueueUserWorkItem(delegate {  // Spawn a Background Thread
    Thread.Sleep(15000);
    ShowMoreVoucherOption(true);
  }); 

If it not the UI Thread, then this code is enough:

Thread.Sleep(15000);
UpdateProgessLable("Your message.");

I guess you do not have enough information on multithreading that involves a UI. Either learn more about it or try these solutions and hope that you are lucky.

Thread.Sleep, hah? Looking at your specs (not the code), I wouldn't go this way. Scan barcode and start the timer. Reset timer every time user clicks YES in-time. If user missed his chance, stop accepting user input and process whats scanned already. You will need some form off locking to prevent processing both, user input and timer at same time, and you will get rid of unnecessary Tread.Sleep.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM