首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >出现了“System.AggregateException”类型的异常,使用ReadAsync

出现了“System.AggregateException”类型的异常,使用ReadAsync
EN

Stack Overflow用户
提问于 2015-12-04 04:55:28
回答 1查看 801关注 0票数 2

背景:我正在使用Visual,with VS Community 2013。我正在制作一个Windows窗体应用程序。用例是:用户单击一个按钮。这样就会弹出一个对话框。然后TCP客户端连接到远程服务器,并等待来自服务器的消息。每次消息到达时,对话框上都会显示文本。如果远程侧关闭套接字,则应关闭对话框。此外,用户还可以单击对话框上的一个按钮,该按钮应该关闭套接字并关闭对话框。

除了最后的要求之外,我的代码似乎实现了所有这些。当用户单击按钮关闭对话框时,我会弹出通常的异常,文本如下:

代码语言:javascript
运行
复制
An exception of type 'System.AggregateException' occurred in mscorlib.dll but was not handled in user code.
Additional information: One or more errors occurred.

选择'Break‘显示条件T.Result = 0被高亮显示。调试器显示T的值为Id = 1, Status = Faulted {7}, Method = "{null}", Result = "{Not yet computed}"

我的问题是:这个错误意味着什么?如何修复它?

下面是对话框代码的相关部分。为了简洁起见,我省略了函数ShowStatus,它只会更新表单上的可视化控件。

代码语言:javascript
运行
复制
Imports Microsoft.VisualBasic
Imports System.Net.Sockets
Imports System.Text

Public Class FormMyDialog
    Private gRequest As String
    Private inbuf(10000) As Byte
    Private inoff As Integer
    Private serv As NetworkStream
    Private sock As System.Net.Sockets.TcpClient

    ' the main form calls this when the user clicks a button
    Public Sub Go(request As String)
        gRequest = request
        ShowDialog()
    End Sub

    ' this is the Close button I have placed on the dialog
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        sock.Close()
    End Sub

    Private Sub FormMyDialog_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
        sock = New System.Net.Sockets.TcpClient()
        ShowStatus("Connecting")
        sock.Connect("127.0.0.1", 53000)
        ShowStatus("Connected")

        serv = sock.GetStream()

        Dim outbuf As Byte() = Encoding.ASCII.GetBytes(gRequest + Chr(10))
        serv.Write(outbuf, 0, outbuf.Length)
        serv.Flush()

        inoff = 0
        ReadLoop()
    End Sub

    Private Sub ReadLoop()
        Dim readlen As Integer
        Dim T As Task(Of Integer)
        T = serv.ReadAsync(inbuf, inoff, inbuf.Length - inoff)
        If T.Result = 0 Then
            sock.Close()
            Dim d As MethodNoArgs(Of Object)
            d = AddressOf Me.Close
            Me.Invoke(d)
            Return
        End If

        readlen = T.Result
        inoff = inoff + readlen
        ProcessInbuf()
        T.ContinueWith(Sub() ReadLoop())
    End Sub

    Public Delegate Sub MethodNoArgs(Of T1)()

    Private Sub ProcessInbuf()
        ' (omitted) processing that calls ShowStatus
        ' and updates inbuf and inoff
    End Sub

End Class
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-04 10:30:21

您已经注意到,AggregateException只是多个可能发生的异常的包装器。

我不完全确定为什么这个函数会失败,但是它可能是由您的代码的奇怪结构引起的。我看到的主要问题是,您没有遵循干净的async-await结构。通常,您不需要在ContinueWith.Result之间乱搞,在这里得到您想要做的事情。

关键是要使用await关键字。这个关键字基本上结合了ContinueWith.Result。这意味着它等待非阻塞直到异步操作完成并返回结果。

你的代码实际上可以归结为这样的东西:

代码语言:javascript
运行
复制
Private Async Sub ReadLoop()
    Dim readlen As Integer

    Do
        readlen = Await serv.ReadAsync(inbuf, inoff, inbuf.Length - inoff)
        inoff = inoff + readlen
        ProcessInbuf() 
        'maybe this should be async too, to wait until the processing is done
    Loop While readlen > 0

    sock.Close()
    Me.Close()
End Sub

使用Await的另一个优点是它还可以打开AggregateException。您只需确保正确处理异常,因为Async Sub可能因异常而终止,并且不会将异常返回给外部类。一旦它通过了第一个Await,就会发生这种情况。但是您的代码一旦通过ContinueWith,就会遇到相同的“问题”。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34081152

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档