9.1 KiB
source_files, generated_at, model, schema_version, sha256
| source_files | generated_at | model | schema_version | sha256 | |
|---|---|---|---|---|---|
|
2026-04-16T02:09:02.781823+00:00 | Qwen/Qwen3-Coder-Next-FP8 | 1 | 4992256eaf51da73 |
SerialConnection
Documentation: SerialConnection Class
1. Purpose
The SerialConnection class provides a serial port–based implementation of the IConnection interface, enabling asynchronous I/O operations over a system serial port (System.IO.Ports.SerialPort). It wraps the .NET SerialPort class to expose standard connection semantics (connect, disconnect, send, receive) using the asynchronous programming model (APM) and Task-based wrappers. Despite implementing methods like SoftConnect, SoftDisconnect, Bind, Listen, and Accept, the class does not support soft disconnection or server-side listening—those methods are stubs or throw exceptions when misused. Its primary role is to allow serial communication to be used interchangeably with other connection types (e.g., TCP) via the IConnection abstraction.
2. Public Interface
All methods and properties are part of the public API unless explicitly marked protected.
| Member | Signature | Description |
|---|---|---|
IsSoftDisconnected |
public bool IsSoftDisconnected { get; private set; } |
Always false. Not used for serial connections. |
SoftConnect() |
public void SoftConnect() |
No-op. Comment notes: "does nothing for serial as we don't have a soft disconnect option yet." |
SoftDisconnect() |
public void SoftDisconnect() |
No-op. Comment notes: "does nothing for serial as we don't have a soft disconnect option yet." |
KeepAliveErrorReceived() |
void IConnection.KeepAliveErrorReceived() |
Explicit interface implementation; no-op. |
Create(string connectString, string hostIPAddress) |
public void Create(string connectString, string hostIPAddress) |
No-op. Does not assign connectString. |
GetConnectionData() |
public string GetConnectionData() |
Returns "". |
GetCurrentDownloadRate() |
public double GetCurrentDownloadRate() |
Returns 0D. |
GetCurrentUploadRate() |
public double GetCurrentUploadRate() |
Returns 0D. |
OnDisconnected |
public event EventHandler OnDisconnected |
Event declared but never raised. |
Connected |
public bool Connected { get; } |
Always false. Not updated on connect. |
ConnectString |
public string ConnectString => _PortName |
Returns the last-assigned port name (e.g., "COM3"). |
Flags |
public System.Net.Sockets.SocketFlags Flags { get; set; } |
Property inherited from IConnection; unused (no socket semantics). |
Create(string PortName) |
public void Create(string PortName) |
Initializes Port with _PortName (note: bug—see Gotchas). Sets _PortName = PortName. |
BeginConnect(...) |
public IAsyncResult BeginConnect(AsyncCallback cb, object state) |
Opens the SerialPort. Throws if Port == null or _PortName is null/empty. Returns null. |
EndConnect(...) |
public void EndConnect(IAsyncResult ar) |
No-op. Throws if Port == null. |
BeginDisconnect(...) |
public IAsyncResult BeginDisconnect(bool reuseSocket, AsyncCallback cb, object state) |
No-op. Throws if Port == null. Returns null. |
EndDisconnect(...) |
public void EndDisconnect(IAsyncResult asyncResult) |
No-op. Throws if Port == null. |
BeginAccept(...) |
public IAsyncResult BeginAccept(AsyncCallback callback, Object state) |
Throws if Port == null. Returns null. |
EndAccept(...) |
public IConnection EndAccept(IAsyncResult asyncResult) |
Returns a new SerialConnection instance (uninitialized—no Port created). Throws if Port == null. |
Bind(int port) |
public void Bind(int port) |
No-op. Throws if Port == null. |
Listen(int backlog) |
public void Listen(int backlog) |
No-op. Throws if Port == null. |
BeginSend(...) |
public IAsyncResult BeginSend(byte[] buffer, int offset, int size, AsyncCallback cb, object state) |
Delegates to SerialPort.BaseStream.BeginWrite(...). Throws if Port == null or cb == null. |
EndSend(...) |
public int EndSend(IAsyncResult ar) |
Calls SerialPort.BaseStream.EndWrite(ar). Returns Port.BytesToWrite. Throws if Port == null. |
SendAsync(...) |
public Task<int> SendAsync(byte[] sendBuffer, int bufferStartOffset, int bufferSizeToSend) |
Wraps BeginSend/EndSend using Task.Factory.FromAsync. |
BeginReceive(...) |
public IAsyncResult BeginReceive(byte[] buffer, int offset, int size, AsyncCallback cb, object state) |
Delegates to SerialPort.BaseStream.BeginRead(...). Throws if Port == null or cb == null. |
EndReceive(...) |
public int EndReceive(IAsyncResult ar) |
Calls SerialPort.BaseStream.EndRead(ar). Throws if Port == null. |
Dispose() |
public void Dispose() |
Calls Dispose(true) and suppresses finalization. |
~SerialConnection() |
~SerialConnection() |
Finalizer calls Dispose(false). |
Dispose(bool) |
protected virtual void Dispose(bool disposing) |
Closes and nulls Port if disposing is true. Sets disposed = true. |
Note
: The class implements
IDisposable.Connectedis never set totrue, andOnDisconnectedis never invoked.
3. Invariants
Connectedis alwaysfalse. It is a read-only property initialized tofalseand never modified._PortNameis set only viaCreate(string PortName).ConnectStringreturns_PortName.Portis only initialized inCreate(string PortName)andEndAccept(...). In the latter case, the newSerialConnectioninstance hasPort == null.BeginConnectis the only method that actually opens the serial port (Port.Open()). No other method affects port state.EndSendreturnsPort.BytesToWrite, which reflects the number of bytes still pending in the transmit buffer—not bytes sent.SoftConnect,SoftDisconnect,Bind,Listen, andBeginAccept/EndAcceptare not functional for serial connections and may throw ifPort == null.IsSoftDisconnectedis alwaysfalseand unused.
4. Dependencies
-
Depends on:
DTS.Common.Interface.Connection(viaIConnectioninterface).System.IO.Ports(forSerialPort).System.Threading.Tasks(forTask<int>).System(forEventHandler,AsyncCallback,IAsyncResult,Exception).
-
Depended on by:
- Unknown from source alone. Presumably used by higher-level connection-handling logic that consumes
IConnection.
- Unknown from source alone. Presumably used by higher-level connection-handling logic that consumes
5. Gotchas
-
Critical Bug in
Create(string PortName):Port = new SerialPort(_PortName); // ❌ Uses uninitialized _PortName _PortName = PortName; // ✅ Sets _PortName *after* useThe
SerialPortconstructor is called with_PortName, which isnullat that point. Should benew SerialPort(PortName). -
Connectedis never updated:
Even afterBeginConnectsucceeds,Connectedremainsfalse. Consumers cannot rely on this property. -
OnDisconnectedis never raised:
The event is declared but never invoked—even duringDisposeorPort.Close(). -
EndAcceptreturns an uninitializedSerialConnection:
The new instance hasPort == null, so callingBeginConnect/Send/Receiveon it will throw. -
SoftConnect/SoftDisconnectare no-ops:
Despite being part ofIConnection, they do nothing. Do not expect disconnection behavior from them. -
BeginDisconnect/EndDisconnectdo not close the port:
OnlyDisposecloses theSerialPort.EndDisconnectis a no-op. -
GetCurrentDownloadRate()/GetCurrentUploadRate()always return0D:
No actual rate tracking is implemented. -
Flagsproperty is unused:
It is aSocketFlagsproperty (fromIConnection) but serial ports do not use socket flags. -
BeginSend/BeginReceiveuseSerialPort.BaseStream:
This is correct for async I/O, but note thatSerialPort.BaseStreamis synchronous under the hood—performance may be suboptimal for high-throughput scenarios. -
No validation of
PortNameinCreate:
Invalid port names (e.g.,"COM999") will only fail atPort.Open()inBeginConnect. -
ConnectStringis misleading:
It holds only the port name (e.g.,"COM3"), not a full connection string. Also, the overloadCreate(string connectString, string hostIPAddress)ignoresconnectString. -
disposedflag prevents double-dispose:
Safe, butPortmay benullafter first dispose—subsequentDisposecalls are no-ops. -
No exception handling in
BeginConnect/EndConnect:
Exceptions fromPort.Open()(e.g.,UnauthorizedAccessException,IOException) propagate directly. -
No cancellation support:
All async methods lackCancellationTokensupport. -
EndSendreturnsBytesToWrite:
This is the number of bytes remaining in the output buffer—not bytes sent. Likely a mistake; should be bytes written (which is implicit inEndWrite’s return value, butEndSenddiscards it and returnsBytesToWriteinstead).