gpt4 book ai didi

vb.net - 使用ReadAsync发生 'System.AggregateException'类型的异常

转载 作者:行者123 更新时间:2023-12-03 11:53:09 26 4
gpt4 key购买 nike

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

除了最后一个要求,我的代码似乎实现了所有这些要求。当用户单击按钮关闭对话框时,我将看到通常的异常弹出窗口,其内容为:

An exception of type 'System.AggregateException' occurred in mscorlib.dll but was not handled in user code.
Additional information: One or more errors occurred.

选择“中断”显示条件 T.Result = 0突出显示。调试器显示 T的值为 Id = 1, Status = Faulted {7}, Method = "{null}", Result = "{Not yet computed}"
我的问题是:此错误是什么意思,我该如何解决?

这是对话框代码的相关部分。为了简洁起见,我省略了 ShowStatus函数,除了更新窗体上的可视控件外,它什么也不做。
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

最佳答案

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

我不能完全确定为什么此功能会失败,但这可能是由于代码的奇怪结构引起的。我看到的主要问题是您没有遵循干净的async-await结构。通常,您不需要弄乱ContinueWith,而.Result确实可以在这里获得您想要的功能。

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

您的代码实际上可以归结为如下所示:

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,您的代码就会成为同样的“问题”。

关于vb.net - 使用ReadAsync发生 'System.AggregateException'类型的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34081152/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com