ReadAsync退出,无法在调试中跟踪

时间:2015-09-30 15:25:44

标签: c# async-await

我有以下代码(_ns是NetworkStream)

await GetResponse(_ns);
btnSend.Enabled = true;

private async Task GetResponse(NetworkStream stream)
{
    while (true)
    {
        var readBuffer = new byte[4096];
        var asyncReader = await stream.ReadAsync(readBuffer, 0, readBuffer.Length);
        txtBoxMessagesIn.Text += Encoding.ASCII.GetString(readBuffer.ToArray()) + Environment.NewLine;
        if (asyncReader <= 0) break;
    }
}

我似乎用我期望的填充整个缓冲区,但btnSend从未启用。

当我在调试模式下运行时,我的while循环运行了几次,我看到asyncReader被设置为不同的值,但它永远不会等于0来打破循环,正如我所料,它只是退出行:

var asyncReader = await stream.ReadAsync(readBuffer, 0, readBuffer.Length);

不会产生任何错误。是什么造成的?我是否需要在Visual Studio中设置一些内容来打破这种类型的错误?

2 个答案:

答案 0 :(得分:3)

0只会在结束时返回ReadAsync。这就是所有流的工作方式。如果流尚未结束(即,对于套接字流,套接字仍然打开),则0将(异步)等待流读取更多字节或结束。

我假设套接字的另一端只是挂开但没有发送更多数据。在这种情况下,任何流读取只会等待它发送更多字节或关闭。没有例外 - 这不是特殊情况。由于套接字未关闭,因此读取的流不会返回while,因此您的/****** Object: UserDefinedFunction [dbo].[CSVToTable] Script Date: 04/28/2013 10:45:17 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE FUNCTION [dbo].[CSVToTable] (@InStr VARCHAR(MAX)) RETURNS @TempTab TABLE (id int not null) AS BEGIN ;-- Ensure input ends with comma SET @InStr = REPLACE(@InStr + ',', ',,', ',') DECLARE @SP INT DECLARE @VALUE VARCHAR(1000) WHILE PATINDEX('%,%', @INSTR ) <> 0 BEGIN SELECT @SP = PATINDEX('%,%',@INSTR) SELECT @VALUE = LEFT(@INSTR , @SP - 1) SELECT @INSTR = STUFF(@INSTR, 1, @SP, '') INSERT INTO @TempTab(id) VALUES (@VALUE) END RETURN END GO 循环不会退出。

答案 1 :(得分:0)

您可以在try / catch语句中包含对ReadAsync的调用,也可以检查任务的结果。我会选择try / catch方法来至少看看最初会发生什么。

try { var asyncReader = await stream.ReadAsync(readBuffer, 0, readBuffer.Length); }
catch (Exception ex) { }

其他方法如下,但是当发生异常时,您无法确定ReadAsync是否正常结束。

var task = stream.ReadAsync(readBuffer, 0, readBuffer.Length);
task.Start();
if (task.Exception != null)
   // see what's going here