问题描述
显示比特币价格的小部件
我没有使用 Json 格式,因为我只需要解析一个字符串,尽管我知道很多人会说要使用 json。无论如何,我想保持软件尽可能简单,但有一个小问题。 我正在使用 webclient 下载源代码并使用计时器更新它。 我想我在每次创建新的网络客户端时都犯了一个错误,因为当我想移动表单时,即使它没有冻结也不能正确移动。 我使用的代码是:
Private Sub webclientbtc()
Dim wc As New Net.WebClient
Dim WBTC As IO.Stream = nothing
wc.Encoding = Encoding.UTF8
WBTC = wc.OpenRead("https://api.binance.com/api/v1/ticker/24hr?symbol=BTCEUR")
Dim btc As String
Using rd As New IO.StreamReader(WBTC)
btc = rd.ReadToEnd
End Using
'---------BTC PRICE---------'
Dim textBefore As String = """lastPrice"":"""
Dim textAfter As String = ""","
Dim startPosition As Integer = btc.IndexOf(textBefore)
startPosition += textBefore.Length
Dim endPosition As Integer = btc.IndexOf(textAfter,startPosition)
Dim textFound As String = btc.Substring(startPosition,endPosition - startPosition)
Dim dNumber As Double = Val(textFound.ToString)
Label1.Text = dNumber.ToString("n2")
'-------------------------------------'
Private Sub Timer1_Tick(sender As Object,e As EventArgs) Handles Timer1.Tick
webclientbtc()
End Sub
计时器间隔为 1000 毫秒,这对我保持更新非常有用。 关于如何避免在每次更新时创建新的网络客户端的任何想法? 谢谢
解决方法
简化,并使用 TAP:
Private wc as New WebClient()
Private Async Sub Timer1_Tick(sender As Object,e As EventArgs) Handles Timer1.Tick
Dim s = Await wc.DownloadStringTaskAsync("https://api.binance.com/api/v1/ticker/24hr?symbol=BTCEUR")
Dim d = JsonConvert.DeserializeObject(Of Dictionary(Of String,String))(s)
Label1.Text = d("lastPrice")
End Sub
需要引用newtonsoft json包并导入,以及导入system.collections.generic
,如果 answer by Caius Jard 太好了,您可以通过使用正则表达式来避免使用 JSON 反序列化器:
Imports System.Net
Imports System.Text.RegularExpressions
Public Class Form1
Dim tim As New Timer()
Private Async Sub UpdateBtc(sender As Object,e As EventArgs)
' temporarily disable the timer in case the web request takes a long time
tim.Enabled = False
' using New Uri() makes sure it is a proper URI:
Dim url = New Uri("https://api.binance.com/api/v1/ticker/24hr?symbol=BTCEUR")
Dim rawJson As String
Using wb As New WebClient()
rawJson = Await wb.DownloadStringTaskAsync(url)
End Using
Dim re = New Regex("""lastPrice"":\s*""([0-9.-]+)""")
Dim lastPrice = re.Match(rawJson)?.Groups(1)?.Value
Dim p As Decimal
lblLastPrice.Text = If(Decimal.TryParse(lastPrice,p),p.ToString("N2"),"Fetch error.")
tim.Enabled = True
End Sub
Private Sub Form1_Load(sender As Object,e As EventArgs) Handles MyBase.Load
UpdateBtc(Nothing,EventArgs.Empty)
tim.Interval = 3000
AddHandler tim.Tick,AddressOf UpdateBtc
tim.Start()
End Sub
Private Sub Form1_FormClosing(sender As Object,e As FormClosingEventArgs) Handles MyBase.FormClosing
If tim IsNot Nothing Then
tim.Stop()
RemoveHandler tim.Tick,AddressOf UpdateBtc
tim.Dispose()
End If
End Sub
End Class
- 无需重复使用 WebClient,创建它并不占用时间。
- 我更喜欢自己实例化计时器:没有要求这样做。
- 最好为控件使用描述性名称:“Label1”什么也不告诉你。