このソリューションConsole.ReadLine()
を使用して、タイムアウトで呼び出したいと思います。
delegate string ReadLineDelegate();
string ReadLine(int timeoutms)
{
string resultstr = null;
ReadLineDelegate d = Console.ReadLine;
IAsyncResult result = d.BeginInvoke(null, null);
result.AsyncWaitHandle.WaitOne(timeoutms);//timeout e.g. 15000 for 15 secs
if (result.IsCompleted)
{
resultstr = d.EndInvoke(result);
Console.WriteLine("Read: " + resultstr);
}
else
{
Console.WriteLine("Timed out!");
// Bug? resource leak? No d.EndInvoke(), which blocks until Console.ReadLine() returns
}
result.AsyncWaitHandle.Close();
return resultstr;
}
しかし、コメンテーターは次のように警告しました:
every ReadLine you call sits there waiting for input.
If you call it 100 times, it creates 100 threads
which don't all go away until you hit Enter 100 times!
...特に、これを永久ループで繰り返し呼び出したいためです。
BeginInvoke()
すべてが必要であることは理解していますが、ブランチでのブロッキング呼び出しはEndInvoke()
望ましくありません。コールが完了しない可能性があるため、コールを完了するまで実行させるのではなく、コールを実行する必要があります。EndInvoke
else
abort
Console.ReadLine()
したがって、この(複雑な)コードはすべて、タイムアウト時に Console.ReadLine を返すのに役立ちましたが、Console.ReadLine を終了して終了したり、別の方法で消えたりすることはありません。
リソースリークに遭遇することなく、これを正しく機能させるにはどうすればよいでしょうか?
NB: MS Calling Sync 呼び出しの非同期呼び出しAsyncWaitHandle.Close()
でアドバイスされたように追加しました