Threading Error

Dennis Hining

Member
Joined
Jun 7, 2021
Messages
12
Programming Experience
Beginner
Using Visual Express 2010, I have the following code in a Form Class for the Browse Button (note the Me.OpenFileDialog declaration is in the Class Declaration area.

VB.NET:
Me.OpenFileDialog1 = New System.Windows.Forms.OpenFileDialog

Private Sub but_Browse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles but_Browse.Click

        '**************************************************************************************************
        With OpenFileDialog1
            .Filter = "MP3 Files (*.mp3)|*.mp3|All Files (*.*)|*.*"
            .FilterIndex = 1
        End With
        If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
            tbox_FileNameMP3.Text = OpenFileDialog1.FileName
        Else
            tbox_FileNameMP3.Text = ""
        End If
End Sub

When running the degugger, I press the Browse Button on the form and get the following error message:
"Current thread must be set to single thread apartment (STA) mode before OLE calls can be made. Ensure that your Main function has STAThreadAttribute marked on it. This exception is only raised if a debugger is attached to the process"

I start the program using a main class:

VB.NET:
Public Class Main
    <STAThread()> Shared Sub Main()
        Dim winForm As Form = New form1
        Application.Run(winForm)
    End Sub
End Class

How do I fix the error?????
 
Last edited by a moderator:
Why are you writing your own Main method to begin with, instead of using the Application Framework? You're not doing anything that seems to justify disabling the Application Framework.
 
I am a beginner and don't understand what you mean by application framework. I tried eliminating the main and using the Form as my start up but that didn't work either.
 
Why are you writing your own Main method to begin with, instead of using the Application Framework? You're not doing anything that seems to justify disabling the Application Framework.
I removed the Main sub and set the Project Properties to: Startup "Form1", Checked Enable Application Frame work, and checked Make Single Instance Application. Still got the same error when I click on the Browse button on Form 1.
 
It sounds like your project might be broken. I would suggest creating a new project and seeing if the same thing happens.

By the way, declaring a field of type OpenFileDialog makes little sense. If you want to reuse one dialogue then add it to the form in the designer and configure it there. Otherwise, create and destroy a new instance every time you want to display it. Using the same instance repeatedly but configuring it in code is not wrong per se, but it sure ain't right.
 
It sounds like your project might be broken. I would suggest creating a new project and seeing if the same thing happens.

By the way, declaring a field of type OpenFileDialog makes little sense. If you want to reuse one dialogue then add it to the form in the designer and configure it there. Otherwise, create and destroy a new instance every time you want to display it. Using the same instance repeatedly but configuring it in code is not wrong per se, but it sure ain't right.
I think you are right in that my code is broken. It is an old project created, I think, in VB.Net 2008 or maybe even an earier version some 10 year+ ago and I'm trying to run it in VB.Net 2010. express To check this, I created a new project with the simple form and a browse button as per the code below. It worked ok but then I added the last line to set the variable to nothing and I got a syntax error. I really don't think I need to set the OpenFileDialog1 to nothing because as soon as the sub runs, it should go out of scope automatically. However, I still would like to know why I get a syntax error on the last statement setting it to nothing.

VB.NET:
Imports System.IO
Public Class Form1

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Dim OpenFileDialog1 As New System.Windows.Forms.OpenFileDialog
        Dim lst As String
        '**************************************************************************************************
        With OpenFileDialog1
            .Filter = "MP3 Files (*.mp3)|*.mp3|All Files (*.*)|*.*"
            .FilterIndex = 1
        End With
        If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
            lst = OpenFileDialog1.FileName
        Else
            lst = ""
        End If
    End Sub
    set OpenFileDialog1 = nothing
End Class
 
Last edited by a moderator:
Firstly, please stop using the Inline code button for code that isn't inline. I already edited your first post and notified you of the issue and you did the same thing again. Use the Code button for blocks of code and the Inline code button only for inline code, like I used it in post #5.

As for your code, it just makes no sense at all. For one thing, you don't use the Set keyword in VB.NET. For another, unless you're initialising a field, you can't set a variable - or do anything else for that matter - outside a method. You also can't access a local variable outside of the method it's declared in. All that would be covered in any beginners tutorial. There's also no point setting the variable to Nothing, even if it was in a place you could, because it loses scope at the end of the method and ceases to exist anyway.

What you should be doing is disposing the object you created. You can do that explicitly but, if you can, you should always use a Using block. Also, if you're going to use a With block there, don't exclude the last two usages of that variable. Better to use an object initialiser if you want to set initial properties. I think these should all be available to you even in VB 2008:
VB.NET:
Imports System.IO

Public Class Form1

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Using OpenFileDialog1 As New OpenFileDialog With {.Filter = "MP3 Files (*.mp3)|*.mp3|All Files (*.*)|*.*",
                                                          .FilterIndex = 1}
            Dim lst As String
            
            If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
                lst = OpenFileDialog1.FileName
            Else
                lst = String.Empty
            End If
        End Using 'Object gets implicitly disposed here'
    End Sub
    
End Class
Finally, that lst variable is useless as it is as well, because it loses scope once the method completes too. You would need to either use it in that method or else declare it as a field.
 
Firstly, please stop using the Inline code button for code that isn't inline. I already edited your first post and notified you of the issue and you did the same thing again. Use the Code button for blocks of code and the Inline code button only for inline code, like I used it in post #5.

As for your code, it just makes no sense at all. For one thing, you don't use the Set keyword in VB.NET. For another, unless you're initialising a field, you can't set a variable - or do anything else for that matter - outside a method. You also can't access a local variable outside of the method it's declared in. All that would be covered in any beginners tutorial. There's also no point setting the variable to Nothing, even if it was in a place you could, because it loses scope at the end of the method and ceases to exist anyway.

What you should be doing is disposing the object you created. You can do that explicitly but, if you can, you should always use a Using block. Also, if you're going to use a With block there, don't exclude the last two usages of that variable. Better to use an object initialiser if you want to set initial properties. I think these should all be available to you even in VB 2008:
VB.NET:
Imports System.IO

Public Class Form1

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Using OpenFileDialog1 As New OpenFileDialog With {.Filter = "MP3 Files (*.mp3)|*.mp3|All Files (*.*)|*.*",
                                                          .FilterIndex = 1}
            Dim lst As String
           
            If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
                lst = OpenFileDialog1.FileName
            Else
                lst = String.Empty
            End If
        End Using 'Object gets implicitly disposed here'
    End Sub
   
End Class
Finally, that lst variable is useless as it is as well, because it loses scope once the method completes too. You would need to either use it in that method or else declare it as a field.
Thanks for feedback. I know the "lst" variable loses scope but this was just a test class to see if the file dialog would open which it did. Finally, using lst="" as opposed to lst=string.empty would seem to me to be a matter of programmer's choice...is there a difference that necessitates the extra typing of String.Empty? Finally, I don't understand what is meant by inline code! The other forum I use for Excel wants ALL code to be encapsulated by /Code and /Code markers.
 
Finally, using lst="" as opposed to lst=string.empty would seem to me to be a matter of programmer's choice...is there a difference that necessitates the extra typing of String.Empty?
That's why I didn't actually bring that up directly, and just left it in the code. I seem to recall having read something about that being the preferred option some time back but I can't recall where and it would make little real difference anyway.
Finally, I don't understand what is meant by inline code! The other forum I use for Excel wants ALL code to be encapsulated by /Code and /Code markers.
What other forums want is irrelevant. Each one works differently and has different options.

As for what inline code is, it should be fairly obvious if you actually look. I said that I used inline code formatting in post #5 and there's only one place that I've used formatting in that post. That same formatting is used in other posts too, including the one you quoted. As you can see, all uses of that formatting are inline, i.e. within the regular flow of the text, as opposed to separate blocks of code. It should generally be used to highlight very short pieces of your text that are actually code. Anything long and/or multiline should be in a code block. Surely you would agree that the formatting that I applied to my own code block and yours is more readable than what you used originally.
 
That's why I didn't actually bring that up directly, and just left it in the code. I seem to recall having read something about that being the preferred option some time back but I can't recall where and it would make little real difference anyway.

What other forums want is irrelevant. Each one works differently and has different options.

As for what inline code is, it should be fairly obvious if you actually look. I said that I used inline code formatting in post #5 and there's only one place that I've used formatting in that post. That same formatting is used in other posts too, including the one you quoted. As you can see, all uses of that formatting are inline, i.e. within the regular flow of the text, as opposed to separate blocks of code. It should generally be used to highlight very short pieces of your text that are actually code. Anything long and/or multiline should be in a code block. Surely you would agree that the formatting that I applied to my own code block and yours is more readable than what you used originally.
Thanks again. Yes, your code is shorter but I also do a lot of programming in VBA where your code won't work and some utility routines I plan to use in both VB.Net and Excel VBA. I am sorry that I assumed this forum was the same. as the other forums I see now that there is a "code block" icon for use of Code. I think it's time to close this thread as I am not able to resolve my initial error issue and apparently nobody else on this forum can either. I will have to reprogram my application code block by code block bit building on the test code that works as a base. Thanks again for help.
 
Back
Top