私は継承したいくつかのコードで好奇心を持っています。以下の単純な例は、プレーンなコンソールアプリケーションに組み込まれている場合の問題を示しています。TcpClient例外デッドロック
WhoIsは5回目のコールで使用許可を得て、メッセージを返して+ソケットをシャットダウンします。 ReadLineAsyncを使用すると、SocketExceptionとIOExceptionが生成されます。これらはキャッチブロック内にキャッチされ、すべてがそうである必要があります。ほとんどの場合、キャッチされず、プログラムが単にハングします。メインスレッドのConsole.WriteLineを呼び出します。この現象は、デバッガの外で.exeファイルを直接実行すると引き続き発生します。
何が起こっているのか誰に見えますか?
Peek()を使って私の問題を実際に解決できますが、私は例外が捕捉されずに何が起こっているのか知りたいのですが、 "デッドロック"です。おそらく、それは何らかのスレッドや文脈の問題です。それが私がやっていることなら、どこでそれを避けることができるのかを知りたいです!
using System;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace AsyncIssueConsoleApplication
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Task.Run(() => LookupAsync("elasticsearch.org")).Result);
Console.WriteLine(Task.Run(() => LookupAsync("elasticsearch.org")).Result);
Console.WriteLine(Task.Run(() => LookupAsync("elasticsearch.org")).Result);
Console.WriteLine(Task.Run(() => LookupAsync("elasticsearch.org")).Result);
Console.WriteLine(Task.Run(() => LookupAsync("elasticsearch.org")).Result);
Console.WriteLine(Task.Run(() => LookupAsync("elasticsearch.org")).Result);
Console.WriteLine(Task.Run(() => LookupAsync("elasticsearch.org")).Result);
Console.WriteLine(Task.Run(() => LookupAsync("elasticsearch.org")).Result);
Console.WriteLine(Task.Run(() => LookupAsync("elasticsearch.org")).Result);
Console.WriteLine(Task.Run(() => LookupAsync("elasticsearch.org")).Result);
Console.WriteLine(Task.Run(() => LookupAsync("elasticsearch.org")).Result);
Console.ReadLine();
}
private static async Task<string> LookupAsync(string domain)
{
StringBuilder builder = new StringBuilder();
TcpClient tcp = new TcpClient();
await tcp.ConnectAsync("whois.pir.org", 43).ConfigureAwait(false);
string strDomain = "" + domain + "\r\n";
byte[] bytDomain = Encoding.ASCII.GetBytes(strDomain.ToCharArray());
try
{
using (Stream s = tcp.GetStream())
{
await s.WriteAsync(bytDomain, 0, strDomain.Length).ConfigureAwait(false);
using (StreamReader sr = new StreamReader(s, Encoding.ASCII))
{
try
{
//This is fine
/*while (sr.Peek() >= 0)
{
builder.AppendLine(await sr.ReadLineAsync());
}*/
//This isn't - produces SocketException which usually isn't caught below
string strLine = await sr.ReadLineAsync().ConfigureAwait(false);
while (null != strLine)
{
builder.AppendLine(strLine);
strLine = await sr.ReadLineAsync().ConfigureAwait(false);
}
}
catch (Exception e)
{
//Sometimes the SocketException/IOException is caught, sometimes not
return builder.ToString();
}
}
}
}
catch (Exception e)
{
return builder.ToString();
}
return builder.ToString();
}
}
}
が
duplicate Q&Aは確かではない、完全に、関係するかもしれませんが、私が見ることができるこのクエリに応答しません推奨:つまり私はのSynchronizationContextについて行う必要があるだろう - 私はすでに(偽)ConfigureAwaitを使用しています。上記のようにコードがデッドロックされ
、スタックトレースがある:
mscorlib.dll!System.Threading.Monitor.Wait(object obj, int millisecondsTimeout, bool exitContext) Unknown
mscorlib.dll!System.Threading.Monitor.Wait(object obj, int millisecondsTimeout) Unknown
mscorlib.dll!System.Threading.ManualResetEventSlim.Wait(int millisecondsTimeout = -1, System.Threading.CancellationToken cancellationToken) Unknown
mscorlib.dll!System.Threading.Tasks.Task.SpinThenBlockingWait(int millisecondsTimeout, System.Threading.CancellationToken cancellationToken) Unknown
mscorlib.dll!System.Threading.Tasks.Task.InternalWait(int millisecondsTimeout = -1, System.Threading.CancellationToken cancellationToken) Unknown
mscorlib.dll!System.Threading.Tasks.Task<string>.GetResultCore(bool waitCompletionNotification = true) Unknown
mscorlib.dll!System.Threading.Tasks.Task<System.__Canon>.Result.get() Unknown
AsyncIssueConsoleApplication.exe!AsyncIssueConsoleApplication.Program.Main(string[] args = {string[0]}) Line 18 C#
にIOExceptionがある:{ "転送接続からデータを読み取ることができません:既存の接続はリモートホストに強制的に切断されました。「}
のSocketExceptionがある:{」確立された接続は、ホストマシン "}
あなたのTCPClientインスタンスを破棄することは役に立ちますか? –
私は 'ConnectAsync'をtryブロックに移動します – Eser
あなたはTCPClientを廃棄していません - (TcpClient tcp = new TcpClient())を使って{...} –