More on FlowSshNet
FlowSsh's .NET interface is implemented in C++/CLR. The following is FlowSshNet's include dependency graph. It illustrates FlowSshNet's reliance on the underlying FlowSshCpp implementation.
As a FlowSshNet user you will first add the FlowSshNet.dll assembly to your project's references, in order to use its functionality available in the Bitvise.FlowSshNet namespace.
Before doing anything with the library, register a handler for [SshNet]OnExceptionInEvent. This event is invoked when there is an uncaught exception in any other event handler. See [SshNet]OnExceptionInEvent for more details.
Handlers in FlowSshNet are implemented as events, and they are invoked from internal worker threads.
As with FlowSshCpp, FlowSshNet classes can be divided into two groups.
- Main classes: Keypair, PublicKey, Client, ClientSessionChannel, ClientSftpChannel
- Handler classes: ProgressHandler, ReceiveHandler, RealPathHandler, StatHandler, SftpHandler, ListHandler, TransferHandler
Events will only be invoked on objects that are active. Handler objects are said to be active when they are in progress. This is between and including their OnStart and OnDone events. Clients are active if they are either connected or connecting. Similarly, channels are active if they are open or opening. The global error handler is active as long as there is an active client or channel.
All handler classes have two events in common, namely OnStart and OnDone. OnStart is invoked when an operation starts and OnDone as soon as it completes. Active handler objects are never garbage collected. This means that you can start several requests and forget about them until their OnDone is invoked. This works because OnStart implicitly creates a strong reference on a handler object. After the matching OnDone event finishes, FlowSshNet dismisses its strong reference on that object. An active handler object also holds a strong reference to the associated main object, and prevents it from being garbage collected in the middle of a request.
All main classes and handler classes implement Dispose and Finalizer methods. You can and should dispose your objects once you no longer need them. After you dispose an active object, no new events will be invoked on it. However, an event already invoked and in progress will possibly still be executing even after your dispose call returns. (Recall that handlers/events in FlowSshNet are called by FlowSshC worker threads.) Nevertheless, the only possible consequence in such cases is that you might get a [System]ObjectDisposedException exception, if the disposed object itself is accessed in the event.
For similar reasons, the same might happen in combination with finalizers on main objects (but not for handler objects; GC does not collect them while they are active because of the internal strong reference mentioned before). Imagine you no longer hold a reference to a connected client object; it then might happen that GC calls the finalizer at the same time its [Client]OnDisconnect or any other event is executing. If you then use the client object from such an event, an ObjectDisposedException will be thrown.
Note that you cannot update Control based UI elements from within handlers/events directly. In .NET, only a thread that owns (has created) a control can modify it. You might use Control.Invoke to get around this issue.