GUI 移动不正常

问题描述

我正在做一个使用 Binance API here

显示比特币价格的小部件

我没有使用 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”什么也不告诉你。