My project (Purpose non descriptive title)
My project (Purpose non descriptive title)
My project (Purpose non descriptive title)
My project (Purpose non descriptive title)
My project (Purpose non descriptive title)
My project (Purpose non descriptive title) My project (Purpose non descriptive title) My project (Purpose non descriptive title) My project (Purpose non descriptive title) My project (Purpose non descriptive title) My project (Purpose non descriptive title) My project (Purpose non descriptive title) My project (Purpose non descriptive title)
My project (Purpose non descriptive title) My project (Purpose non descriptive title)
My project (Purpose non descriptive title)
Go Back  Xtreme Visual Basic Talk > > > My project (Purpose non descriptive title)


Reply
 
Thread Tools Display Modes
  #1  
Old 08-15-2011, 11:45 AM
Coel's Avatar
Coel Coel is offline
Regular
 
Join Date: Feb 2011
Location: UK
Posts: 54
Default My project (Purpose non descriptive title)


Hello, after my last httpwebrequest (forum poster) project i have decided to make an IRC client. I am taking more concepts that i have learned from my books and trying to insert them into my projects.

Over the course of the next few weeks i will have some questions but rather then start multiple threads i would like to (if this is allowed?) to keep them all here for easy and future reference.

User Controls

I have started to use User controls and would like to know if i am communicating between forms/controls correctly and also if my "control base" class is the correct way to go. I only ask this because i have never seen an example and made it up.

My MainForm has a docked (filled) Panel that i use to load/dispose the UC in.

I use a private variable to handle the UC at startup

Code:
    Private _userControl As New UserControlBase

 Public Sub New()
        InitializeComponent()
        _userControl = New UserControlBase
    End Sub

I came up with the idea to use a "ControlBase" to handle the UC loading/disposing.

UserControlBase

Code:
Option Strict On

''' <summary>
''' Responsible for handling user control's Loading/Unloading
''' </summary>
''' <remarks></remarks>

Public Class UserControlBase

    Private _currentControl As UserControl

    ' Gets or sets the current user control.
    Property UserControlShown() As UserControl
        Get
            Return _currentControl
        End Get
        Set(ByVal value As UserControl)
            If value IsNot Nothing Then
                _currentControl = value
            End If
        End Set
    End Property

End Class
Loading of the UC

Code:
    Private Sub DisplayUserControl(ByVal uc As UserControl)
        If _userControl Is Nothing Then
            _userControl = New UserControlBase
        End If

        uc.Dock = DockStyle.Fill
        userControlPanel.Controls.Add(uc)
        _userControl.UserControlShown = uc
    End Sub
Disposing

Code:
    Private Sub DisposeUserControl()

        If _userControl Is Nothing Then
            Exit Sub
        End If

        Dim uc As UserControl = _userControl.UserControlShown

        If uc IsNot Nothing Then
            uc.Dispose()
            userControlPanel.Controls.Remove(uc)
            uc = Nothing
        End If
    End Sub
Now currently i only have 1 form and 2 UC. The Two UC need to share information but since neither is loaded at the same time i must use properties. How ever i am duplicating the same #region of properties in both UC and this seems silly to reuse the same code twice. Hoping there is a better way.

The UC that handles the connection sets the properties values as so when btnconnect raises the click event.

Code:
 Private Sub ConnectToServer()
        ' TODO: temporary forced use of server details.
        Dim serverParts As String() = lvwServers.Items(0).Text.Split(New Char() {"/"c}, 2)

        Me.Server = serverParts(0)
        Me.port = CInt(serverParts(1))
        Me.Channel = Me.txtChannels.Text ' TODO: split
        Me.ChannelNick = Me.txtGloNick.Text
        Me.ChannelAltNick = Me.txtGloNickAlt.Text
        Me.UserName = Me.txtUserName.Text
        Me.RealName = Me.txtRealName.Text
        RaiseEvent ConnectionCompletedEventArgs(Me, EventArgs.Empty)
    End Sub
MainForm catches this and calls the next UC

Code:
#Region " EventArghs "
    ''' <summary>
    ''' Responsible for catching User Control Servers button connect click.
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub ConnectEventArghs() Handles _connection.ConnectionCompletedEventArgs

        If _connection Is Nothing Then
            ' TODO: Major issue with we invoke this.....
            Exit Sub
        End If

        ' Get server values.
        Dim uc As New ChannelView
        uc.Server = _connection.Server
        uc.port = _connection.port
        uc.Channel = _connection.Channel
        uc.ChannelNick = _connection.ChannelNick
        uc.ChannelAltNick = _connection.ChannelAltNick
        uc.UserName = _connection.UserName
        uc.RealName = _connection.RealName

        DisposeUserControl()
        DisplayUserControl(uc)
    End Sub
#End Region
Now i wont copy the properties because they are obvious but i have the list of properties in UC1 & UC2. Am i sharing information wrong?

Thanks for any assistance i know its a long post.

PS Atma i do not want to bump an old thread but i have been away. You replied to me about the naming controls and it makes perfect sense. Not sure why i liked the idea i suggested. Also your blog has some great information.

thank you
__________________
I think of the company advertizing "Thought Processors" or the college pretending that learning BASIC suffices or at least helps, whereas the teaching of BASIC should be rated as a criminal offence: it mutilates the mind beyond recovery
Reply With Quote
  #2  
Old 08-15-2011, 01:28 PM
AtmaWeapon's Avatar
AtmaWeaponMy project (Purpose non descriptive title) AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

Whenever you find yourself wishing there were an easy way to gather a group of related properties, you are wishing for a class. Classes are how you group information and share/hide it. Don't make three classes with the same properties: make one class and share that instance between them.

You're close to something sort of like a Presentation Model pattern, but to say you're using one of those you have to work to separate UI from logic. Let's ignore that bigger topic for how you might accomplish this with what you've got. Start with a ConnectionInfo (or whatever name seems appropriate) class:
Code:
Public Class ConnectionInfo
    Public Property Server As String
    Public Property Port As Integer
    ...
End Class
Now the user control that gets connection information should be a producer and consumer of the ConnectionInfo class:
Code:
Public Class ConnectionControl
    Inherits UserControl

    Private _connectionInfo As ConnectionInfo

    Public Property ConnectionInfo
        Get
            UpdateConnectionInfo()
            Return _connectionInfo
        End Get
        Set(ByVal value As ConnectionInfo)
            _connectionInfo = value
            UpdateUI()
        End Set
    End Property

    ' Called when the connection information needs to be pulled from the UI
    Private Sub UpdateConnectionInfo()
        If _connectionInfo Is Nothing Then
            _connectionInfo = New ConnectionInfo()
        End If

        _connectionInfo.Server = txtServer.Text
        _connectionInfo.Port = CInt(txtPort.Text)
        ...
    End Sub

    ' Called when the UI needs to be updated from the connection info
    Private Sub UpdateUI()
        If _connectionInfo Is Nothing Then
            Return
        End If

        txtServer.Text = _connectionInfo.Server
        txtPort.Text = _connectionInfo.Port.ToString()
        ...
    End Sub
End Class
Perhaps the second user control only reads information from the connection info; for this kind of relationship I like to make the constructor require a ConnectionInfo to illustrate it's a write-only dependency:
Code:
Public Class ChannelView
    Inherits UserControl

    Private _connectionInfo As ConnectionInfo

    Public Sub New(ByVal connectionInfo As ConnectionInfo)
        InitializeComponent()

        _connectionInfo = connectionInfo
    End Sub
End Class
So looking at what you've described of your application architecture, you could integrate things like this. When the connection user control raises its event:
Code:
Dim connectUI As ConnectionControl = CType(sender, ConnectionControl)
Dim connectionInfo As ConnectionInfo = connectUI.ConnectionInfo

If connectionInfo Is Nothing
    Return
End If

' Optional: stash the ConnectionInfo in the form so it can pass it to
' other user controls

Dim channelView As NewChannelView(connectionInfo)

DisposeUserControl()
DisplayUserControl(channelView)
Now instead of trying to pass properties around, you're passing an object. It's easier to understand and less tedious to type.

My rule of thumb for sharing data among controls is for any given logical concept, I can pass a maximum of two things. If a connection required only a server name, passing a String is fine. But for a server/port pair, I might think about making a class. For server/port/channel, there's too many arguments and I'd rather make one class for the pieces of information. Don't take this too far and make a "god object" with properties for everything under the sun though: it's fine to separate one object into many and in many cases better.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #3  
Old 08-16-2011, 12:19 PM
Coel's Avatar
Coel Coel is offline
Regular
 
Join Date: Feb 2011
Location: UK
Posts: 54
Default

Perfectly explained atmaweapon. It was this part that made the penny drop

Code:
Public Class ChannelView
    Inherits UserControl

    Private _connectionInfo As ConnectionInfo

    Public Sub New(ByVal connectionInfo As ConnectionInfo)
        InitializeComponent()

        _connectionInfo = connectionInfo
    End Sub
End Class
For some reason when i used a class before of properties i did not think about passing the variable _connectioninfo to the constructor and this was what was failing me. Defining a New instance of connectioninfo which obviously would have no information.

I did not really understand your last paragraph. would you be so kind to rephrase?

thanks
__________________
I think of the company advertizing "Thought Processors" or the college pretending that learning BASIC suffices or at least helps, whereas the teaching of BASIC should be rated as a criminal offence: it mutilates the mind beyond recovery
Reply With Quote
  #4  
Old 08-16-2011, 01:28 PM
passel's Avatar
passelMy project (Purpose non descriptive title) passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,026
Default

Quote:
Originally Posted by Coel View Post
...I did not really understand your last paragraph. would you be so kind to rephrase?

thanks
AtmaWeapon's "Rule of Thumb" (guide):
When passing data between objects:
If there is only one thing to pass, then pass that thing.
If there are only two things to pass, perhaps pass the two things, or create a class to hold the two and pass that.
If there are more than two things to pass, always create a class to contain the things and pass that.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #5  
Old 08-16-2011, 01:49 PM
AtmaWeapon's Avatar
AtmaWeaponMy project (Purpose non descriptive title) AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

Passel said it nicely, the fuzzy part is determining if your thing has too much information in it. i.e. the property isn't always recursive.

Here's illustrations by showing bad then good; the top example is always the "bad" one:

If there is one thing to pass, just pass the thing
Code:
Public Class Employee
    Public Property Name As String
End Class

' Somewhere in your code...
Dim candidate As New Employee("Bob")
Hire(candidate)
Code:
Hire("Bob")
If there are only two things to pass, think about creating a class.
Note: For this example, neither snippet is bad, so I'll only use one code block.
Code:
RevealSquare(3, 4)

' OR

RevealSquare(New Point(3, 4))
If there are more than two things to pass, always use a class.
Code:
DisplayEmployee("Alice", "McLafferty", "18", "555-555-5555", 2500)

' Also bad:
DisplayEmployee(4)

' When implementation looks like:
Sub DisplayEmployee(index As Integer)
    Dim firstName = _firstNames(index)
    Dim lastName = _lastNames(index)
    ...
End Sub
Code:
Public Class Employee
    Public Property FirstName As String
    Public Property LastName As String
    ...
End Class

' Somewhere else... (looks bad without a lot of context actually.)
Dim alice As New Employee(...)
DisplayEmployee(alice)
The final rule is much more fuzzy. It involves deciding if some of many pieces of information are actually related. For example, assume we had this sub (with abbreviated syntax):
Code:
DisplayCatAndDog(catName, catAge, catBreed, dogName, dogAge, dogBreed)
It would be silly to make a class named CatAndDog with six properties. Cats and dogs may have the same properties, but it makes sense to separate them into two classes with three properties each:
Code:
DisplayCatAndDog(someCat, someDog)
It may make sense to have an Animal class from which Cat and Dog derive; then you could provide as many as you want in any order:
Code:
Sub DisplayAnimals(ByVal ParamArray animals() As Animal)

'... somewhere else
DisplayAnimals(someCat, someDog, anotherCat, ...)
But then there's cases where it can be more convenient to let you use the non-class versions; consider the many ways to draw a rectangle:
Code:
DrawRectangle(somePen, x, y, width, height)
' OR
Dim p As New Point(x, y)
Dim s As New Size(width, height)
DrawRectangle(somePen, New Rectangle(p, s))
' OR
Dim rect As New Rectangle(x, y, width, height)
DrawRectangle(somePen, rect)
' OR
Dim p As New Point(x, y)
Dim s As New Size(width, height)
Dim rect As New Rectangle(p, s)
DrawRectangle(somePen, rect)
They exist because there's tons of different ways to calculate a rectangle, and it'd be annoying to create a new Rectangle to do so if it's easiest for your algorithm to work with 4 integers.

It's all encapsulated in a larger rule of thumb: optimize for programmer joy. If it's hard to write your code, something's wrong. Figure out a way to make it easy. If creating a class for some parameters introduces a hurdle, don't do it. If you can't keep track of the parameters to a method, make a class. There are no absolute rules in programming, but there are solutions that help manage complexity: you should seek those until some project requirement forces your hand.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #6  
Old 08-18-2011, 11:37 AM
Coel's Avatar
Coel Coel is offline
Regular
 
Join Date: Feb 2011
Location: UK
Posts: 54
Default

passel: thank you for refining that, made perfect sense.

Atamaweapon that explanation really defined it for me. I think you summed it up perfect here "optimize for programmer joy." I think the main factor here is i am not a pro or do programming for a living so should make my own life easy.

-------------------------------

I would like to state why i wont to keep all my questions here is often i feel i rush a head of my self. Even though i know something works does not always mean there cant be a better way of doing a task. So want to ask questions after each new step i take before i go onto the next.

This also helps me not to be spoon fed as i am showing you pros my work before i ask.

---------------------------

Implements IDisposable

After learning user controls have no closed method i was told i should implement IDisposable.

Now at the top i
Code:
    Public Class IRC : Implements IDisposable
and at the bottom

Code:
        Private Sub Dispose() Implements IDisposable.Dispose
            If Me.IrcConnection IsNot Nothing Then
                Me.IrcConnection = Nothing
            End If

            If Me.IrcStream IsNot Nothing Then
                Me.IrcStream = Nothing
            End If

            If Me.IrcReader IsNot Nothing Then
                Me.IrcReader = Nothing
            End If

            If Me.IrcWriter IsNot Nothing Then
                Me.IrcWriter = Nothing
            End If

            If _thread IsNot Nothing Then
                _thread = Nothing
            End If
        End Sub
But it never seems to be called. I have tried adding debug.writeline to see when its called but it never is.

am i missing something here? This is all from my IRC.vb class.

Now my next question regarding this is when i close MainForm user control ChannelView is currently loaded with a new instance of IRC.vb class. Now MainForm has no way to send the command on closing _irc.disconnect to ChannelView that calls IRC class.

This to me is a brain puzzler. Not even sure i could hook an event? Currently on form closing my form vanishes but IRC class is still connected. I need to dis-attach all resources.

Am i right in thinking i need to over ride the disposed method and handle this before the internal own disposed method is called?
__________________
I think of the company advertizing "Thought Processors" or the college pretending that learning BASIC suffices or at least helps, whereas the teaching of BASIC should be rated as a criminal offence: it mutilates the mind beyond recovery
Reply With Quote
  #7  
Old 08-18-2011, 01:39 PM
AtmaWeapon's Avatar
AtmaWeaponMy project (Purpose non descriptive title) AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

Quote:
Now my next question regarding this is when i close MainForm user control ChannelView is currently loaded with a new instance of IRC.vb class. Now MainForm has no way to send the command on closing _irc.disconnect to ChannelView that calls IRC class.

This to me is a brain puzzler. Not even sure i could hook an event? Currently on form closing my form vanishes but IRC class is still connected. I need to dis-attach all resources.

Am i right in thinking i need to over ride the disposed method and handle this before the internal own disposed method is called?
Yep. The GC never calls Dispose(): it's your responsibility to call it on any class that needs it. When forms close, they automatically call Dispose() on all of their child controls. If you want your ChannelView control to disconnect its IRC connection when this happens, override the ChannelView control's Dispose() method and have it tell the IRC class to quit:
Code:
Protected Override Sub Dispose(ByVal disposing As Boolean)
    MyBase.Dispose(disposing)

    If disposing Then
        _myIRC.Dispose()
    End If
End Sub
Don't forget to call the base class version, or you could cause problems. (That's one of the major flaws with the Dispose() pattern: it requires as much discipline as COM's reference counting or C's memory management did, and it can look like it's working while it fails.)
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #8  
Old 08-18-2011, 02:05 PM
PlausiblyDamp's Avatar
PlausiblyDampMy project (Purpose non descriptive title) PlausiblyDamp is offline
Ultimate Contributor

Forum Leader
* Expert *
 
Join Date: Nov 2003
Location: Newport, Wales
Posts: 2,058
Default

Be aware that setting things to Nothing in VB.Net as part of your class cleanup is often a waste of time, if your class is going out of scope and is eligible for garbage collection then the variables it contains are going to be eligible as well - no need to set them to nothing.

If these variables implement IDisposable though then you should be calling .Dispose on them rather than setting them to nothing.
__________________
Intellectuals solve problems; geniuses prevent them.
-- Albert Einstein

Posting Guidelines Forum Rules Use the code tags
Reply With Quote
  #9  
Old 08-20-2011, 04:00 AM
Coel's Avatar
Coel Coel is offline
Regular
 
Join Date: Feb 2011
Location: UK
Posts: 54
Default

See this is where i come to before. I override the dispose method but i get an error saying

Error 2 'Protected Overrides Sub Dispose(disposing As Boolean)' has multiple definitions with identical signatures

which makes senses if already there in the designer but why is it not being called? Should i delete that?

and thanks for pointing out dispose over nothing
__________________
I think of the company advertizing "Thought Processors" or the college pretending that learning BASIC suffices or at least helps, whereas the teaching of BASIC should be rated as a criminal offence: it mutilates the mind beyond recovery
Reply With Quote
  #10  
Old 08-20-2011, 04:47 AM
PlausiblyDamp's Avatar
PlausiblyDampMy project (Purpose non descriptive title) PlausiblyDamp is offline
Ultimate Contributor

Forum Leader
* Expert *
 
Join Date: Nov 2003
Location: Newport, Wales
Posts: 2,058
Default

The error makes it look like you have defined the Dispose( as Boolean) twice, you only need one instance of this method. Could you give an example of the code you have that is causing this error?
__________________
Intellectuals solve problems; geniuses prevent them.
-- Albert Einstein

Posting Guidelines Forum Rules Use the code tags
Reply With Quote
  #11  
Old 08-20-2011, 09:54 AM
AtmaWeapon's Avatar
AtmaWeaponMy project (Purpose non descriptive title) AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

Quote:
Originally Posted by Coel View Post
See this is where i come to before. I override the dispose method but i get an error saying

Error 2 'Protected Overrides Sub Dispose(disposing As Boolean)' has multiple definitions with identical signatures

which makes senses if already there in the designer but why is it not being called? Should i delete that?

and thanks for pointing out dispose over nothing
For forms and *maybe* UserControls there's likely one auto-generated in the Designer.vb file. For some reason Microsoft didn't create an easy way for you to extend it; they optimized for people who only ever use the designer and never write their own classes. Cut that Dispose() out of the designer, paste it in your file, then add the code you need to it.

If it's not in a form or user control, I cannot answer the question without seeing code. I'm confused by "Why isn't it being called?". It likely is, but it doesn't automatically dispose your IRC class. It isn't generated by parsing your source file and disposing any members that can be disposed. It's generated in response to interacting with the designer. If something wasn't dropped on the form through the designer, the designer-generated code doesn't know about it.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #12  
Old 08-24-2011, 01:26 PM
Coel's Avatar
Coel Coel is offline
Regular
 
Join Date: Feb 2011
Location: UK
Posts: 54
Default

Ok that makes sense, but not very helpful of m$. Under NormalView user control i now have

Code:
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso _irc IsNot Nothing Then
                _irc.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub
which is being called. the IRC class disposed method i can not test if disposing correctly since i am getting an exception on closing from the IRC class.

Unable to read data from the transport connection: A blocking operation was interrupted by a call to WSACancelBlockingCall.

which at first i thought was due to thread aborting and trying to do an operation. But then i removed any call to abort the thread and set the thread IsBackGround to true. Which i am lead to believe this will terminate on it's on when mainform closes?

Code:
            While (InlineAssignHelper(ircCommand, _streamReader.ReadLine())) IsNot Nothing
Am i going about terminating this class/thread all wrong here? This thrown exception is stopping me from disposing the User control.

The only other option i can think of would be aborting the thread and catching ThreadAbortException and disposing there. but does not seem very graceful.....

The said class is here if you need it. Hopefully you wont because i dont want to be spoon fed here but nudged along in the right direction.

http://pastebin.com/g3b5RHPR

PS if you do notice some silly coding that can be made better please feel free to hint


*edit* thread abort is still keeping the thread alive

od :/
__________________
I think of the company advertizing "Thought Processors" or the college pretending that learning BASIC suffices or at least helps, whereas the teaching of BASIC should be rated as a criminal offence: it mutilates the mind beyond recovery

Last edited by Coel; 08-24-2011 at 02:12 PM.
Reply With Quote
  #13  
Old 08-24-2011, 03:05 PM
Coel's Avatar
Coel Coel is offline
Regular
 
Join Date: Feb 2011
Location: UK
Posts: 54
Default

Ok update:

I decided to go back to using a backgroundworker instead. This works fine closing but dose not call dispose (idisposable Irc client class)or allows me to catch cancel pending

Code:
#Region " Instance Variables "
    Private WithEvents _bgwIrc As New BackgroundWorker
#End Region

#Region "Constructor"
    Public Sub New()
        _bgwIrc = New BackgroundWorker
    End Sub
#End Region
Code:
#Region "Public Methods"
    Public Sub InitializeConnection()
        _bgwIrc.WorkerSupportsCancellation = True
        _bgwIrc.RunWorkerAsync()
    End Sub

    Public Sub CancelConnection()
        _bgwIrc.CancelAsync()
    End Sub

    Private Sub ConnectionAttempt_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles _bgwIrc.DoWork
  
' code removed.............................................

        Do
            If _bgwIrc.CancellationPending Then
                e.Cancel = True
   else

' code removed.............................................
        
        Loop While _bgwIrc.CancellationPending <> True
    End Sub

#End Region
__________________
I think of the company advertizing "Thought Processors" or the college pretending that learning BASIC suffices or at least helps, whereas the teaching of BASIC should be rated as a criminal offence: it mutilates the mind beyond recovery
Reply With Quote
  #14  
Old 08-24-2011, 03:23 PM
PlausiblyDamp's Avatar
PlausiblyDampMy project (Purpose non descriptive title) PlausiblyDamp is offline
Ultimate Contributor

Forum Leader
* Expert *
 
Join Date: Nov 2003
Location: Newport, Wales
Posts: 2,058
Default

You need to call the Dispose yourself, it isn't called automatically by the framework.
__________________
Intellectuals solve problems; geniuses prevent them.
-- Albert Einstein

Posting Guidelines Forum Rules Use the code tags
Reply With Quote
  #15  
Old 08-24-2011, 04:02 PM
Coel's Avatar
Coel Coel is offline
Regular
 
Join Date: Feb 2011
Location: UK
Posts: 54
Default

Quote:
Originally Posted by PlausiblyDamp View Post
You need to call the Dispose yourself, it isn't called automatically by the framework.
Hi Plausiblydamp, I thought it was called when you call the dispose method on the class?

NormalView Usercontrol (when user control is closing should call_irc class dispose method IDispose?)
Code:
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso _irc IsNot Nothing Then
                _irc.Dispose()
                _irc = Nothing
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub


edit*

Ok i have now managed to dispose correctly. I will show my work tomorrow as going to sleep

thanks guys
__________________
I think of the company advertizing "Thought Processors" or the college pretending that learning BASIC suffices or at least helps, whereas the teaching of BASIC should be rated as a criminal offence: it mutilates the mind beyond recovery

Last edited by Coel; 08-24-2011 at 04:33 PM.
Reply With Quote
  #16  
Old 08-24-2011, 05:52 PM
AtmaWeapon's Avatar
AtmaWeaponMy project (Purpose non descriptive title) AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

I told you multiple times you had to call Dispose() yourself.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #17  
Old 08-25-2011, 12:14 PM
Coel's Avatar
Coel Coel is offline
Regular
 
Join Date: Feb 2011
Location: UK
Posts: 54
Default

Ha ha Atmaweapon(Now added to my FF dictionary), i did notice. I also had tried my self but thought i was handling it wrong since i was getting exceptions thrown at disposing.

This i know now was due to my threading. I think i was handling or doing something wrong.

Code:
    Dim _thread As New Thread(AddressOf ConnectionAttempt)

    Public Sub New(ByVal connectionInfo As ConnectionInfo)
        _thread = New Thread(AddressOf ConnectionAttempt)
    End Sub
	
	Public Sub Disconnect_MultiThread()
        If _thread IsNot Nothing Then
            Connection.Close()
            _thread.Abort()
            _thread = Nothing
            Me.Dispose()
        End If
    End Sub
	
	Public Sub Connect_MultiThread(ByVal KeepAlive As Object)
        _thread.Start(KeepAlive)
    End Sub

    Public Sub ConnectionAttempt(ByVal KeepAlive As Object)
	
	' and so on ........
I now use a backgroundworker which i know is a wrap around for threading and set WorkerSupportsCancellation to true. What would you suggest is better. a BGW or threading as before for my IRC class? or can that question even be answered?

My only problem with a BGW is when i call cancel and i check during the loop it does not check.


Code:
    Private Sub ConnectionAttempt_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles _bgwIrc.DoWork
        ' removed for pasting...
        Do
		' removed for pasting...

            ' Connect with the IRC server.
            ' Authenticate our user
            ' removed for pasting...

            ' Listen for commands
            Dim ircCommand As String = String.Empty

            While (InlineAssignHelper(ircCommand, _streamReader.ReadLine())) IsNot Nothing

                If _bgwIrc.CancellationPending Then
                    e.Cancel = True
                    Exit Do
                Else

                    RaiseEvent ServerResponseRawDataEventArghs(ircCommand)

                    If fromServer = domaintld Then

                        RaiseEvent ServerResponseAllEventArgh(ircCommand)

                        ' Server message's onconnect, onjoin
                        ' removed for pasting...

                    Else
                        ' removed for pasting...
                    End If
                End If

            End While

        Loop While _bgwIrc.CancellationPending <> True
    End Sub
(full loop un edited http://pastebin.com/XDdXBaa4)


*edit*

Now removed the BGW since it kept disconnecting and looping the connection. (Why....lol) one of lifes mysteries but now introduced lambdas since it allows me to pass a type. which brings me back to that exception that keeps being thrown when closing lol.

I am literally looping myself now with these posts like my code i am working on is lol.


*EDIT*

Finally sussed it. I did not think the thread was ever aborting because of the time length. Which was my fault since i did not even give the thread a helping hand at closing the connection.

Code:
 Private _mtIRC As New Thread(DirectCast(Sub() InitializeConnection(False), ThreadStart))
To close the connection:

Code:
    Public Sub CloseConnection()
        If Me.Connection IsNot Nothing Then
            Me.Connection.Close()
            Me.Connection = Nothing
        End If

        If _mtIRC.IsAlive Then
            _mtIRC.Abort()
        End If
    End Sub
Closing the connection then aborting would throw
System.Threading.ThreadAbortException right away allowing me to catch this and dispose of the class.

So my final over riding dispose method looks like

Code:
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso _irc IsNot Nothing Then
                _irc.CloseConnection()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub
Yeh yeh i know this should of been obvious logic

#cancel connection
#abort thread
#catch exception
#dispose class

Quite glad i finally got it.

any comments on my final example on threading?
__________________
I think of the company advertizing "Thought Processors" or the college pretending that learning BASIC suffices or at least helps, whereas the teaching of BASIC should be rated as a criminal offence: it mutilates the mind beyond recovery

Last edited by Coel; 08-25-2011 at 02:32 PM.
Reply With Quote
  #18  
Old 08-25-2011, 02:37 PM
Coel's Avatar
Coel Coel is offline
Regular
 
Join Date: Feb 2011
Location: UK
Posts: 54
Default

oh and speaking of annoying exceptions every time i debug i get

A first chance exception of type 'System.IO.FileNotFoundException' occurred in mscorlib.dll

but what file is missing? the only time i used IO. was before i moved to using my.settings. But i removed all code (one small sub creating a file)

so whats calling it? the exception is clear but to where is not.
__________________
I think of the company advertizing "Thought Processors" or the college pretending that learning BASIC suffices or at least helps, whereas the teaching of BASIC should be rated as a criminal offence: it mutilates the mind beyond recovery
Reply With Quote
  #19  
Old 08-26-2011, 01:36 AM
Coel's Avatar
Coel Coel is offline
Regular
 
Join Date: Feb 2011
Location: UK
Posts: 54
Default

Interesting after going to debug -exceptions and creating a breakpoint.

Could not load file or assembly 'System.XmlSerializers, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The system cannot find the file specified.

Code:
        <Global.System.Configuration.UserScopedSettingAttribute(),  _
         Global.System.Diagnostics.DebuggerNonUserCodeAttribute()>  _
        Public Property ServerList() As Global.System.Collections.Specialized.StringCollection
            Get
                Return CType(Me("ServerList"),Global.System.Collections.Specialized.StringCollection)
            End Get
            Set
                Me("ServerList") = value
            End Set
        End Prop
But my stringcollection loads perfectly and saves. Will dig deeper after work tonight. Work now
__________________
I think of the company advertizing "Thought Processors" or the college pretending that learning BASIC suffices or at least helps, whereas the teaching of BASIC should be rated as a criminal offence: it mutilates the mind beyond recovery
Reply With Quote
  #20  
Old 08-26-2011, 11:26 AM
AtmaWeapon's Avatar
AtmaWeaponMy project (Purpose non descriptive title) AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

Thread.Abort() is very heavy-handed, and it's strongly recommended that you do not do so. Read the documentation; it outlines some scenarios that can destablize the runtime and crash your application. It's meant to be a last-resort "Oh no the world is on fire everybody to the shelter!" kind of thing, not a "Hey I'd like this thread to stop executing now." thing. Seriously, the documentation indicates Thread.Abort() can interrupt a type initializer. That's equivalent to saying, "In rare cases, after calling Thread.Abort() your application will start reporting that 2 + 2 = 'Apple'." The more appropriate thing to do is have flags that tell the thread "It's time to quit" so it can tidy up after itself and quit in a nice manner. This is why if I have to maintain a Thread object, it's *always* in terms of a wrapper that hides it:
Code:
Class WorkerThread
    
    Private _shouldStop As Boolean
    Private _thread As Thread

    Public Sub Start()
        _thread = New Thread(AddressOf DoWork)
        _thread.Start()
    End Sub

    Public Sub Stop()
        _shouldStop = True
    End Sub

    Private Sub DoWork(ByVal state As Object)
        While someCondition
            If _shouldStop Then
                Exit While
            End If

            ' do work
        End While

        RaiseEvent Me.Stopped(Me, EventArgs.Empty)
    End Sub

    ' Optional
    Public Event Stopped As EventHandler
End Class
It can get a heck of a lot more complicated than that: getting a reliable Dispose() implementation is a bit of a bother that requires knowing about waithandles. It's a fun topic for another (forum) thread. The benefits to having a separate class are great; at the very least it's easier to put breakpoints inside the thread and understand where you are.

It's no coincidence that it looks a lot like how a BackgroundWorker is used; I like the BGW class but it's probably inappropriate for this application. BGW uses thread pool threads and is intended for tasks that complete and are canceled in exceptional scenarios. Managing your own thread is better for situations where there's no real "finish" except for when you ask the thread to stop. So it's not wrong to avoid BGW, though I admit from time to time when I'm in a hurry I abuse it for this kind of task.

I've got no clue on the exception, but it may be a red herring. When the IDE reports a "first chance" exception, it means the exception has been thrown but the CLR hasn't done any work to see if there's a Try..Catch that handles it yet. You can configure VS to break on any first-chance exceptions, but it's a feature I usually leave turned off until I need it. Sometimes an exception is thrown as part of the normal operation of an algorithm. For example, File.Exists() is volatile information. The file might exist this moment, but it could be deleted before you operate on it. So if you're opening a file that is allowed to not exist (like a settings file), it's common to use a pattern like this:
Code:
Try
    Using reader As StreamReader = File.OpenText("blah.txt")
        ' do some stuff
    End Using
Catch ex As FileNotFoundException
    ' The file's not there 
    LoadDefaults()
End Try
In this case, you'll see a first-chance FileNotFoundException because it will be thrown when the file isn't there. But all is well, because the Try..Catch expects this exception and loads default settings if the file doesn't exist. So the first-chance exception's a false alarm.

If all you're seeing is a first-chance exception, it's inside Microsoft's code, and your application is behaving as expected, I'd say it's just some noise in the output window. I only worry about first-chance exceptions when the code isn't behaving as I expect and the exception is handled somewhere; that tells me some code is erroneously handling the exception.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
My project (Purpose non descriptive title)
My project (Purpose non descriptive title)
My project (Purpose non descriptive title) My project (Purpose non descriptive title)
My project (Purpose non descriptive title)
My project (Purpose non descriptive title)
My project (Purpose non descriptive title) My project (Purpose non descriptive title) My project (Purpose non descriptive title) My project (Purpose non descriptive title) My project (Purpose non descriptive title) My project (Purpose non descriptive title) My project (Purpose non descriptive title)
My project (Purpose non descriptive title)
My project (Purpose non descriptive title)
 
My project (Purpose non descriptive title)
My project (Purpose non descriptive title)
 
-->