I am using the SSH.NET library to implement a file system watcher on a remote linux server using the inotifywait command. Essentially it is a wrapper around:
ssh myhost "inotifywait -m -e close_write --format '%:e %f' /dropzone"
That command will print out (to STDOUT):
CLOSE_WRITE:CLOSE foo
CLOSE_WRITE:CLOSE bar
CLOSE_WRITE:CLOSE baz
Which is simple enough to parse and turn into events. Anyway, my c# code is essentially:
var privateKeyFile = new PrivateKeyFile(identity);
var client = new SshClient(hostname, username, privateKeyFile);
SshCommand command = null;
IAsyncResult result = null;
try
{
client.Connect();
command = client.CreateCommand("inotifywait -m -e close_write --format '%:e %f' " + dropZone);
result = command.BeginExecute();
Console.WriteLine("Watching for events");
var reader = new StreamReader(command.OutputStream);
string line = null;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}
Console.WriteLine("Reached end of stream");
}
finally
{
if (client != null)
{
Console.WriteLine("Close the connection");
client.Dispose();
}
}
Console.WriteLine("Press enter to quit");
Console.ReadLine();
And running it results in this output after a single file is written:
Watching for events
CLOSE_WRITE:CLOSE baz
Reached end of stream
Close the connection
Press enter to quit
The Watching for events
shows up immediately and will wait for the first file to be written (blocking wait as I would expect from StreamReader
). However, the the next ReadLine
, rather than another blocking wait, returns null (which indicates end of stream), even though the command is still happily running. I know that I can change the loop thusly:
while (!result.IsCompleted)
{
line = reader.ReadLine();
if (line != null)
{
Console.WriteLine(line);
}
}
Which results in:
Watching for events
CLOSE_WRITE:CLOSE baz
CLOSE_WRITE:CLOSE bar
CLOSE_WRITE:CLOSE foo
...
As desired, but it gets rid of the blocking wait for new input which means the loop is constantly spinning (obviously undesired...)
Can you explain this behavior? Any suggestions for another approach?
---- UPDATE ----
It looks like the library is in the process of being migrated to github, and updated. I have submitted this issue in an attempt to resolve this problem.