Button.PerformClick() across thread - vb.net

See this code:
Imports System.Threading
Private trd As Thread
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
trd = New Thread(AddressOf ThreadTask)
trd.IsBackground = True
trd.Start()
End Sub
Sub ThreadTask()
Thread.Sleep(50)
Button4.PerformClick()
End Sub
Private Sub Button4_Click(sender As System.Object, e As System.EventArgs) Handles Button4.Click
Me.Close()
End Sub
I'm trying to simulate a button click from a different thread, but the following error occurs: "An unhandled exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll", at the Button4.PerformClick() line.
How can I use this function across threads?

You need to execute UI commands on the same thread as the controls were created on. We can do this with a delegate. This can be done very easily with a lambda.
Replace Button4.PerformClick() with this:
Me.Invoke(Sub() Button4.PerformClick())

Related

"'frmExport' not declared. It may be inaccessible due to its protection level" in VB 2019

I just added a new form to a VB 2019 project. It's a project that I first created in VB 2010. It adds the form OK, but it gives me a BC30451 error when I run a showdialog command on it. The new form has only 2 buttons on it with no code. Any help?
Here's all the code in the new form:
Public Class frmExport
Public Sub frmExport_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Hide()
End Sub
End Class
Code from the calling form:
Private Sub Button5_Click(sender As System.Object, e As System.EventArgs) Handles Button5.Click
' Data Export
Timer1.Stop()
Me.TopMost = False
frmExport.ShowDialog()
Me.TopMost = True
Timer1.Start()
End Sub

Cannot access a disposed object in VB.NET

Having a small issue.
I am receiving a Cannot access a disposed object error for Form1
Upon clicking a menu item on the main form - the below Sub is called, which opens another form Form1
Private Sub ToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem.Click
If (Not Form1.Visible) Then
Form1.Show(Me)
End If
End Sub
Within Form1, there is a Try block. If it isn't passed, Form1 should show a message box, before closing down. The message appears, but it's then that I receive the error (where it says Form1.Show(Me))
Private Sub Form1_Load(ByVal sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Try
'DO STUFF
Catch
MsgBox("Error loading in data. Please contact an administrator")
Me.Close()
Return
End Try
End Sub
I am quite new to this type of programming, and struggling to fix the problem even after searching similar problems. Could someone please assist or point me in the right direction?
EDIT: So looks like this is due to trying to close the form during the Load event. So my question now is, are there any simple alternatives? I've found ways of doing this in C#, but not a lot for vb.net
Here is one option:
Private loadFailed As Boolean = False
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Try
'...
Catch ex As Exception
loadFailed = True
End Try
End Sub
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
If loadFailed Then
MessageBox.Show("Load failed")
Close()
End If
End Sub
In that case, the form will show with the message over it, then it will close when the message is dismissed. Here's an option that will not display the form:
Friend Module Form1Manager
Public Sub ShowForm1(owner As Form)
If Not Form1.Visible Then
Try
'...
'Pass data to Form1 here.
Form1.Show(owner)
Catch ex As Exception
MessageBox.Show("Load failed")
End Try
End If
End Sub
End Module
and, to use that:
Private Sub ToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem.Click
Form1Manager.ShowForm1(Me)
End Sub

Error System.NotSupportedException was unhandled by user code

I try to get automatic click on a button on a page on my website
I have try multiple things and i can not get out of this exception
This is My code
Well wen i press the button1 its come an error
I describe below code
Public Class Form5
Dim CheckButton, skip_ad_button As HtmlElement
Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
WebBrowser1.ObjectForScripting = True
WebBrowser1.ScriptErrorsSuppressed = True
End Sub
Private Sub Form5_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub WebBrowser1_DocumentCompleted(sender As Object, e As WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted
skip_ad_button = WebBrowser1.Document.GetElementById("skip_ad_button")
CheckButton = WebBrowser1.Document.GetElementById("skip_ad_button")
If Not skip_ad_button Is Nothing Then
skip_ad_button.InnerText = "skip_ad_button" 'Replace testID by the ID you want
End If
If Not CheckButton Is Nothing Then
'some code here
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
WebBrowser1.Navigate("http:\\mediaads.eu/proxy")
End Sub
End Class
This is the error
System.NotSupportedException was unhandled by user code
HResult=-2146233067
Message=Property is not supported on this type of HtmlElement.
Source=System.Windows.Forms
StackTrace:
at System.Windows.Forms.HtmlElement.set_InnerText(String value)
at WindowsApplication1.Form5.WebBrowser1_DocumentCompleted(Object sender,
WebBrowserDocumentCompletedEventArgs e) in \Documents\Visual Studio
2012\Projects\WindowsApplication1\WindowsApplication1\Form5.vb:line 23

Marquee Progress Bar with Background Worker in VB.NET

I have a main form with a progressbar at the bottom status strip. It is set to marquee style. I want it to keep animating when
I run a long function. But when the function hits, the form and everything on it freezes, so II used a backgroundworker
to run the long function. But this gave me the following error inside the MyClass.BigFunction() code.
Cross-thread operation not valid: Control 'frmMainNew' accessed from a thread other than the thread it was created on.
"frmMainNew" is the main form on which the progressbar and backgroundworker are. I pass the form as a parameter to the MyClass object
when I initialize it.
This is the first time I am using backgroundworker, so what else do I need?
I have already looked at these examples and tried them, but nothing works. (1, 2, 3, 4, 5, 6).
I have to use this for other functions too.
My code:
Private WithEvents bgw As BackgroundWorker
Private Sub frmMainNew_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Try
Me.SuspendLayout()
'Other Functions
w_AddBackgroundWorkerForProgressBar()
Me.ResumeLayout()
Catch ex As Exception
Scube.Planner.ErrorHandler.DisplayError(ex)
End Try
End Sub
Private Sub w_AddBackgroundWorkerForProgressBar()
bgw = New BackgroundWorker
AddHandler bgw.DoWork, AddressOf bgw_DoWork
AddHandler bgw.RunWorkerCompleted, AddressOf bgw_Completed
'AddHandler bgw.ProgressChanged, AddressOf bgw_ProgressChanged
End Sub
Private Sub MyButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyButton.Click
Try
bgw.WorkerSupportsCancellation = True
bgw.RunWorkerAsync()
'MyClass.BigFunction() <--- Originally called from here
Catch ex As Exception
Scube.Planner.ErrorHandler.DisplayError(ex)
Finally
Me.Cursor = Cursors.Default
End Try
End Sub
Private Sub bgw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles bgw.DoWork
'Do your lenghty operations here
MyClass.BigFunction()
System.Threading.Thread.Sleep(10000)
End Sub
Private Sub bgw_Completed(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) Handles bgw.RunWorkerCompleted
If Not IsNothing(e.Error) Then
MessageBoxEx.Show(e.Error.ToString)
End If
ProgressBar1.Hide()
End Sub
Private Sub w_ShowProgressBar()
ProgressBar1.Show()
Me.Refresh()
System.Windows.Forms.Application.DoEvents()
End Sub
You cant and should not access your frmMainNew from your 'BigFunction()'. It is working on a separate thread and does not have access to the UI thread. We need to see what you are doing inside your bigfunction to tell you the problem. Im going to take a guess and say you are trying to update the progressbar values from within that function? If this is so then is the incorrect way to do so.
What you need to do is, set the progress in your BigFunction like so:
bgw.ReportProgress(Progress/Percentage)
and have an event for the progress changed and inside of that event is where you update the progress bar.
Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
Progressbar1.value = e.ProgressPercentage
End Sub

Thread is not getting called

I am trying to call a thread on a button click event. i dont fell my code is not making any syntax error. but its not working.
Private Sub btnHisStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnHisStart.Click
thrHis = New Thread(AddressOf threadHistorical)
thrHis.Start()
End Sub
Private Sub threadHistorical()
'code
End Sub
Add this line and check it
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = False