嗨,我正在解析 Json API
使用我从 quicktype.io 获得的类文件
Imports System.Runtime.CompilerServices
Imports Newtonsoft.Json
Namespace HotBit
Partial Public Class TradeCollection
<JsonProperty("error")>
Public Property [Error] As Object
<JsonProperty("result")>
Public Property Result As List(Of Resulta)
<JsonProperty("id")>
Public Property Id As Long
End Class
Partial Public Class Resulta
<JsonProperty("id")>
Public Property Id As Long
<JsonProperty("time")>
Public Property Time As Long
<JsonProperty("price")>
Public Property Price As String
<JsonProperty("amount")>
<JsonConverter(GetType(ParseStringConverter))>
Public Property Amount As Long
<JsonProperty("type")>
Public Property Type As TypeEnum
End Class
Public Enum TypeEnum
Buy
Sell
End Enum
Partial Public Class TradeCollection
Public Shared Function FromJson(ByVal json As String) As TradeCollection
Return JsonConvert.DeserializeObject(Of TradeCollection)(json, Settings)
End Function
End Class
Public Module Serialize
<Extension()>
Public Function ToJson(ByVal self As TradeCollection) As String
Return JsonConvert.SerializeObject(self, Settings)
End Function
End Module
Friend Module Converter
Public ReadOnly Settings As JsonSerializerSettings = New JsonSerializerSettings With {
.MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
.DateParseHandling = DateParseHandling.None
}
End Module
Friend Class ParseStringConverter
Inherits JsonConverter
Public Overrides Function CanConvert(ByVal t As Type) As Boolean
Return t Is GetType(Long) OrElse t Is GetType(Long?)
End Function
Public Overrides Function ReadJson(ByVal reader As JsonReader, ByVal t As Type, ByVal existingValue As Object, ByVal serializer As JsonSerializer) As Object
If reader.TokenType = JsonToken.Null Then Return Nothing
Dim value = serializer.Deserialize(Of String)(reader)
Dim l As Long
If Long.TryParse(value, l) Then
Return l
End If
Throw New Exception("Cannot unmarshal type long")
End Function
Public Overrides Sub WriteJson(ByVal writer As JsonWriter, ByVal untypedValue As Object, ByVal serializer As JsonSerializer)
If untypedValue Is Nothing Then
serializer.Serialize(writer, Nothing)
Return
End If
Dim value = CLng(untypedValue)
serializer.Serialize(writer, value.ToString())
Return
End Sub
Public Shared ReadOnly Singleton As ParseStringConverter = New ParseStringConverter()
End Class
Friend Class TypeEnumConverter
Inherits JsonConverter
Public Overrides Function CanConvert(ByVal t As Type) As Boolean
Return t Is GetType(TypeEnum) OrElse t Is GetType(TypeEnum?)
End Function
Public Overrides Function ReadJson(ByVal reader As JsonReader, ByVal t As Type, ByVal existingValue As Object, ByVal serializer As JsonSerializer) As Object
If reader.TokenType = JsonToken.Null Then Return Nothing
Dim value = serializer.Deserialize(Of String)(reader)
Select Case value
Case "buy"
Return TypeEnum.Buy
Case "sell"
Return TypeEnum.Sell
End Select
Throw New Exception("Cannot unmarshal type TypeEnum")
End Function
Public Overrides Sub WriteJson(ByVal writer As JsonWriter, ByVal untypedValue As Object, ByVal serializer As JsonSerializer)
If untypedValue Is Nothing Then
serializer.Serialize(writer, Nothing)
Return
End If
Dim value = CType(untypedValue, TypeEnum)
Select Case value
Case TypeEnum.Buy
serializer.Serialize(writer, "buy")
Return
Case TypeEnum.Sell
serializer.Serialize(writer, "sell")
Return
End Select
Throw New Exception("Cannot marshal type TypeEnum")
End Sub
Public Shared ReadOnly Singleton As TypeEnumConverter = New TypeEnumConverter()
End Class
End Namespace
在我得到的计时器里面
CronologiaTrades.Stop()
' Dim downloadTasks As New List(Of Task(Of String))
Dim s = Await wc.DownloadStringTaskAsync(TextBox1.Text) 'https://api.hotbit.io/api/v1/market.deals?market=KIBA/USDT&limit=150&last_id=1521100930
' downloadTasks.Add(s)
'Await Task.WhenAll(downloadTasks)
Dim tc = TradeCollection.FromJson(s)
RichTextBox4.Clear()
For Each r As Resulta In tc.Result
RichTextBox4.Text &= UnixTimeStampToDateTime(CDbl(r.Time)).ToString("HH:mm:ss") & " - " & r.Amount.ToString() & " - " & r.Price.ToString() & " - " & r.Type.ToString() & vbCr
Next
CronologiaTrades.Start()
Else
End If
End If
它使用该函数将 unix 时间戳转换为 HH-mm-ss
Public Shared Function UnixTimeStampToDateTime(ByVal unixTimeStamp As Double) As DateTime
Dim dtDateTime As System.DateTime = New DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc)
dtDateTime = dtDateTime.AddSeconds(unixTimeStamp).ToLocalTime()
Return dtDateTime
End Function
一切正常,但我可以看到表单在每个刻度(1 秒)处“阻塞”。 我的意思是,我对它的工作原理并不感到失望,但我基本上为其他 3 个类似的 API(来自 Quicktype.io 的类文件,相同的 WebClient 代码 ecc)做同样的工作,当它们运行时,我不' 没有看到这种“形式阻塞”。 我想问您在哪里可以改进我的代码,以便使其在不冻结表单的情况下运行,即使是瞬间。
这是我录制的 gif,它显示了其他人如何工作以及如何创建块。 虽然只是几毫秒的事情,但是看着却很烦人。 (这可能是函数 UnixTimeStampToDateTime 没有以异步方式运行?如果是,我怎样才能使其异步?)
编辑:我尝试删除对 rtb 中函数的调用,并且“gui 块”减少更多,但仍然存在。
谢谢
Gif updated,显示了使用和不使用 unixtimestamptodatetime 函数的行为。
Note:此问题总结整理于How to improve this async cycle