Download screen (standby)

I am looking for a universal method for implementing a standby screen during long operations. I used streams several times earlier, but I have the feeling that I implemented it either very poorly or too much trouble (and copying / pasting is horrible!).

I want this to be as general and simple as possible, so I don’t have to load the BackgroundWorker to handle all kinds of crap, which complicates the job.

Here is what I would like to do - note that this may differ from what is actually possible / best / using VB.NET, Framework 2.0 (so no anonymous methods):

  Private Sub HandleBtnClick(sender as Object, e as EventArgs) Handles Button.Click LoadingScreen.Show() 'Do stuff here, this takes a while!' Dim Result as Object = DoSomethingTakingALongTime(SomeControl.SelectedObject) LoadingScreen.Hide() ProcessResults(Result) End Sub 

Now the application is completely single-threaded, so everything works in a GUI thread. I need to have access to objects in DoSomethingTakingALongTime() without getting exceptions for cross-threads. The GUI thread is waiting for the completion of some method (which takes a lot of time), and the LoadingScreen form should remain responsive (it is animated / has a progress LoadingScreen / etc.).

Is this an acceptable / good approach, or do I see that this method is too simplified? What is the best practice on this? And most importantly: how could I implement such a system? As I mentioned, I have very little experience with slicing, so be careful :-)

+4
source share
3 answers

Your problem is that you get a cross-thread exception when you try to pass Worker thread data to your ui thread. what you need to do is check InvokeRequired and begininvoke before setting up controls on your ui so that you don't get this error:

 Private Sub work_CrossThreadEvent(ByVal sender As Object, ByVal e As System.EventArgs) Handles work.CrossThreadEvent If Me.InvokeRequired Then Me.BeginInvoke(New EventHandler(AddressOf work_CrossThreadEvent), New Object() {sender, e}) Return End If Me.Text = "Cross Thread" End Sub 

just change the New EventHandler part to the event handler you are using.

I also think that using a background worker is not a bad method for your working classes, just create a class for your work and use the background worker to make the material for streaming a little as follows:

 Public MustInherit Class Worker Protected WithEvents worker As BackgroundWorker Public Sub New() worker = New BackgroundWorker() worker.WorkerReportsProgress = True worker.WorkerSupportsCancellation = True End Sub Public Sub Start() If (Not worker.IsBusy AndAlso Not worker.CancellationPending) Then worker.RunWorkerAsync() End If End Sub Public Sub Cancel() If (worker.IsBusy AndAlso Not worker.CancellationPending) Then worker.CancelAsync() End If End Sub Protected MustOverride Sub Work() Private Sub OnDoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles worker.DoWork Work() End Sub Public Event WorkCompelted As RunWorkerCompletedEventHandler Private Sub OnRunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) Handles worker.RunWorkerCompleted OnRunWorkerCompleted(e) End Sub Protected Overridable Sub OnRunWorkerCompleted(ByVal e As RunWorkerCompletedEventArgs) RaiseEvent WorkCompelted(Me, e) End Sub Public Event ProgressChanged As ProgressChangedEventHandler Private Sub OnProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) Handles worker.ProgressChanged OnProgressChanged(e) End Sub Protected Overridable Sub OnProgressChanged(ByVal e As ProgressChangedEventArgs) RaiseEvent ProgressChanged(Me, e) End Sub End Class Public Class ActualWork Inherits Worker Public Event CrossThreadEvent As EventHandler Protected Overrides Sub Work() 'do work here' WorkABit() worker.ReportProgress(25) WorkABit() worker.ReportProgress(50) WorkABit() worker.ReportProgress(75) WorkABit() worker.ReportProgress(100) End Sub Private Sub WorkABit() If worker.CancellationPending Then Return Thread.Sleep(1000) RaiseEvent CrossThreadEvent(Me, EventArgs.Empty) End Sub End Class 

disclaimer .. the bit is rusty with vb, but you should get this idea.

+4
source

In your thread, use Application.Run (yourform) to get what you want.

Please note that you need to tell the form in order to close it somehow.

0
source

I hope you do not find this useless - but I would ask, WHY do you want a multi-threaded standby screen to appear on the screen? The reason for using streaming primarily is because the user interface remains responsive and long operations are performed in the background.

Otherwise, you can simply have a ProgressBar in the FormLoading control and periodically update it with DoSomethingTakingALongTime. This will not require threads at all.

0
source

All Articles