Repository navigation
Monitors and streaming
Commands that do not simply answer once: ping, torch, monitor-traffic, /listen. Pick the shape by how
long you want the answer to run.
| You want | Use | Transports |
|---|---|---|
| the current values, once | a snapshot helper | all |
| the rows a command produces in a bounded time | ExecuteListWithDuration / ExecuteListUntilDone |
Api, ApiSsl; ExecuteListUntilDone on all |
| rows as they come, until you stop | ExecuteWithCallback / LoadWithCallback |
all |
| a notification whenever a table changes | LoadListenWithCallback |
all |
The helpers return one snapshot and finish — no cancelling, no threads:
using tik4net.Objects;
using tik4net.Objects.Interface;
using tik4net.Objects.Tool;
InterfaceMonitorTraffic traffic = connection.GetInterfaceMonitorTrafficSnapshot("ether1");
Console.WriteLine($"{traffic.RxBitsPerSecond} / {traffic.TxBitsPerSecond}");
foreach (ToolPing reply in connection.Ping("10.0.0.1", 4))
Console.WriteLine($"{reply.Host} {reply.Time}");More of them — Traceroute, GetEthernetMonitorSnapshot, RomonPing, … — are on
Entity helpers.
Run a command, collect its rows for a while, and get them back as a list. ExecuteListWithDuration is binary API only
(Streaming capability); ExecuteListUntilDone runs on every transport.
| Method | Ends when | Use for |
|---|---|---|
ExecuteListWithDuration(duration) |
the duration is spent, or the command ends first; then sends /cancel
|
commands that never end by themselves (torch) |
ExecuteListUntilDone(timeout) |
the router says !done; the timeout is a safety net |
commands that end by themselves (ping count=5) |
LoadWithDuration<T>(duration) |
as ExecuteListWithDuration, typed |
var torch = connection.CreateCommand("/tool/torch",
connection.CreateParameter("interface", "ether1"));
var rows = torch.ExecuteListWithDuration(TimeSpan.FromSeconds(10), out bool wasAborted, out string? reason);
if (wasAborted)
Console.WriteLine("stopped early: " + reason); // the router's message, or why the connection was lost- The overload without
outparameters throwsTikCommandAbortExceptioninstead. ItsInnerExceptionis the cause: the router's error as the specific trap type (TikNoSuchItemException,TikNoSuchCommandException, … orTikCommandTrapException), or aTikCommandFatalExceptionfor a lost connection. -
ExecuteListUntilDonethrows the router's error directly, as the specific trap type, and a lost connection asTikCommandFatalException; only its timeout is aTikCommandAbortException. - Off the binary API
ExecuteListUntilDoneis the transport's read of the command, and its timeout ends a read still running withTikCommandAbortException. On a CLI connection the cancel follows itsCancellationMode: underCooperative(the default) the router's command is let run out first and the exception comes then, underAbandonAndCloseit comes at the deadline and the connection is closed.
On net8.0 the same two reads exist as IAsyncEnumerable — rows arrive as the router sends them.
ExecuteListUntilDoneAsync runs on every transport with AsyncCommands: off the binary API it is the awaited list,
its rows yielded once the read has ended (not streamed); ExecuteListWithDurationAsync needs Streaming.
using tik4net; // TikCommandStreamingExtensions
await foreach (var row in torch.ExecuteListWithDurationAsync(TimeSpan.FromSeconds(10), cancellationToken))
Console.WriteLine(row.GetResponseField("tx"));- A router error or a lost connection ends the enumeration with
TikCommandAbortException, after the rows already delivered, so a truncated read is never a complete one. ItsInnerExceptionis the cause, as above.
Start a command, get each row in a callback, stop it when you are done. The callbacks run on a background thread — marshal to the UI thread yourself.
using tik4net.Objects;
using tik4net.Objects.Tool;
ITikCommand torch = connection.LoadWithCallback<ToolTorch>(
item => Console.WriteLine(item),
error => Console.WriteLine("ERROR: " + error),
connection.CreateParameter("interface", "ether1"),
connection.CreateParameter("port", "any"));
Console.ReadLine();
torch.CancelAndJoin();-
LoadWithCallback<T>gives typed entities;command.ExecuteWithCallback(row => …)gives raw rows. -
The error callback receives the router's error as the specific trap type (
TikNoSuchItemException,TikNoSuchCommandException, … orTikCommandTrapException), as every other read throws it. -
To be told when a load has ended, pass an
onDonecallback. It runs once when the load ends without an error: after the last row, or whenCancel()or your ownClose()of the connection stopped it. After an error — the router's, or a lost connection — only the error callback runs, so cleanup that must run on every ending goes in both, or afterCancelAndJoin(). The same on every transport and onTikFakeConnection:connection.LoadWithCallback<ToolTorch>(item => Console.WriteLine(item), error => Console.WriteLine(error), () => Console.WriteLine("done"), connection.CreateParameter("interface", "ether1"));
-
Cancel()asks the command to stop;CancelAndJoin()also waits until the reading thread has ended. -
CancelAndJoin(TimeSpan)bounds the wait: it returnsfalsewhen the thread did not end in time, and throwsTikConnectionReceiveTimeoutExceptionwhen the router never answered the cancel. -
Needs the
Listencapability — every shipped transport has it.
LoadListenWithCallback<T> reports changes to a table — a new or changed row, and a deleted one by its .id:
using tik4net.Objects;
using tik4net.Objects.Interface;
ITikCommand listen = connection.LoadListenWithCallback<Interface>(
onChangeCallback: iface => Console.WriteLine($"{iface.Name} running={iface.Running}"),
onDeletedCallback: id => Console.WriteLine($"{id} deleted"),
onExceptionCallback: ex => Console.WriteLine(ex.Message));
Console.ReadLine();
listen.CancelAndJoin();- Rows that already exist are not reported — only later changes.
- Errors, including a failure of the first read, arrive in
onExceptionCallback; the call itself does not throw.
| Transport | How rows arrive |
|---|---|
Api, ApiSsl
|
pushed by the router as they happen |
WinboxNative, WinboxNativeMac
|
monitors through the router's own WinBox windows (typed values); listen by re-reading and comparing |
| CLI transports | a continuous monitor polls a one-shot snapshot; a finite one (ping, traceroute) streams its rows; torch has its own reader. Listen re-reads and compares |
Rest, RestSsl
|
listen re-reads and compares. A monitor's rows arrive all at once when the command ends — RouterOS buffers the whole HTTP response, so give it a count or duration
|
- Where listen is emulated, the table is read once before
LoadListenWithCallbackreturns, so the call takes as long as one read of the table (a second or more through RoMON or over MAC-Telnet). - On a CLI connection a change you make on the same connection can go unreported — make it on a second one; see Threading and concurrency.
- Async and cancellation — awaitable one-shot commands
- Entity helpers — ping, traceroute and the snapshot helpers
-
Connection types & capabilities —
ListenandStreamingper transport - High-level API — reading data
Start
Connecting
- Connecting to a router — setup, options, connection string
- Transports & capabilities — the matrix
- Threading & concurrency
- API · API-SSL
- REST
-
CLI transports
- Telnet · SSH · WinBox CLI
- MAC-layer transports — no IP needed
- WinBox native · GUI-like syntax
- RoMON — through a neighbouring router
- MNDP discovery
Working with data
- Low-level API — raw sentences
- ADO.NET-like API — commands, parameters
- CLI raw commands · tips & tricks
- Command translation
- Async & cancellation
- Monitors & streaming — ping, torch, listen
O/R mapper
-
High-level API
- Reading data · Create, update, delete
- Change tracking · List merge
- TikField · Value types · Helpers
- Entity reference — every covered menu
- Custom entities
Safety
- Safe Mode — rollback protection
- Exception handling
RouterOS
Testing & diagnostics
Extending & tools
Project