shell subclass losing value of property

This worked for me with an httpsocket but not working with a shell:

Subclass an httpsocket
Add a delegate
Add a property of the type of the delegate
Set the property to the addressof a method
In the pagereceived event, invoke the property

Works great with httpsocket. But with a shell:

Subclass a shell
Add a delegate
Add a property of the type of the delegate
Set the property to the addressof a method
In the completed event, invoke the property

I get a nilobjectexception at the last step. Looking at it in the debugger, the property is nil. However, stepping through the whole thing, the property has a value from construction until it hits the completed event. Then it suddenly becomes nil. I wonder if it is some sort of scope issue, but the instance of the subclass still exists. Is there some fundamental difference with delegates between httpsockets and shells or is something else going on?

This works:

[code]Class MyShell Inherits Shell

Delegate Sub MyDelegate()
mMyDelegate As MyDelegate

Sub Constructor()
mMyDelegate = AddressOf Completed
End

Sub Completed()
mMyDelegate.Invoke()
End

Sub Completed()
MsgBox(“Works”)
End

End[/code]

Dim sh As New MyShell() sh.Mode = 1 sh.Execute("")

That works for me if the method to invoke is inside the class, per your example. However, with passing in a method from outside the class and assigning it to a property, the property is still being set to nil in the completed event.

Assuming window1 has a method named “completed” and you create the shell in window1:

dim sh as new MyShell(addressof completed) sh.mode = 1 sh.execute("")

[code]Class MyShell Inherits Shell

Delegate Sub MyDelegate()
mMyDelegate As MyDelegate

Sub constructor(d as myDelegate)
mmyDelegate = d
End Sub

Sub Completed()
mMyDelegate.Invoke()
End

Sub Completed()
MsgBox(“Works”)
End

End[/code]

mmyDelegate has a value after calling Constructor but has a nil value when it gets to the completed event.

My guess is this is not shell related. But without seeing code it is almost impossible to tell – as you have seen I have typed some code based on your instructions. To no avail…

Try converting the property to a computed property and in the setter add “break” or “if value = nil then break” and see if it’s getting set from somewheres.

Trying that it doesn’t break until I get a nilobjectexception when trying to invoke it.

This is what I have. I modified the original example to pass in the address of method from outside the class:

Window1 has this method:

Sub completed() MsgBox("Works") End Sub

Window1 has a button with the action:

Dim sh As New MyShell(AddressOf completed) sh.Mode = 1 sh.Execute("")

I have a class called myShell with the following:

delegate:

Delegate Sub myDelegate()

event handler:

Sub Completed() mmyDelegate.Invoke() End Sub

method:

Sub constructor(d as myDelegate) mmyDelegate = d End Sub

property:

mmyDelegate As myDelegate

Edit: to clarify, myShell is a subclass of Shell

[quote=248133:@Scott Griffitts]Dim sh As New MyShell(AddressOf completed)
sh.Mode = 1
sh.Execute("")[/quote]
sh is going out of scope before the event is called. Store it in a property someplace so this doesn’t happen and you’ll get “Works”.

Sub Button1.Action() Dim sh As New MyShell(AddressOf completed) // Dim sh is the problem sh.Mode = 1 sh.Execute("") End
sh.Mode = 1 means that the shell is running asynchronously. So when the Completed event should be raised on sh, sh does not exist anymore as it has been destructed at the end of Button1.Action. With it of course the reference to the delegate instance is cleared.

You need to make sh a property of the window (or something else which will hold a reference to it, so it stays alive long enough):

[code]Class Window1 Inherits Window

Property sh As MyShell

Sub Button1.Action()
sh = New MyShell(AddressOf completed)
sh.Mode = 1
sh.Execute("")
End[/code]

Thank you Will and Eli. I was convinced the debugger was telling me that the shell instance was still around. I need to ponder how to handle an indeterminate number of these properties as I need to call this shell class multiple times at the same time.

Use an array.

I use a Dictionary as shared property with the PID as Key and delegate as Value.

(I also remove the entry in the completed event so I can use the Dictionary.Count for my rate limiter.)