winforms 如何加快币安币价解析?

htrmnn0y  于 2023-02-09  发布在  其他
关注(0)|答案(1)|浏览(99)

我试图创建一个机器人,下多个订单的Binance和我需要一个快速的硬币价格解析。
我在用这个代码解析代码

Dim price as decimal       
Private Async Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    Timer1.Stop()
    Dim downloadTasks As New List(Of Task(Of String))
    Dim dogebusd = wc1.DownloadStringTaskAsync("https://api.binance.com/api/v1/ticker/price?symbol=DOGEBUSD")
    downloadTasks.Add(dogebusd)
    Await Task.WhenAll(downloadTasks)

    Dim d = JsonConvert.DeserializeObject(Of Dictionary(Of String, String))(dogebusd.Result)
    Dim PREZZO As Decimal = CDec(Val((d("price")).ToString))
    
    price = CDec((PREZZO))
    
    Timer1.Start()
End Sub

但当价格倾销或抽水真的很快,即使是10毫秒或100毫秒的计时器滴答声是不是有效的。我想知道这是否是最快的方式可能或如果我可以改进代码。谢谢
以下吉米的建议:

Dim price As Decimal
Private ReadOnly _timer As New PeriodicTimer(TimeSpan.FromSeconds(1))

Private Async Sub Timer1_Tick(sender As Object, e As EventArgs) Handles _timer.Tick
    timer1.stop
    Dim dogebusdTask = HttpClient.GetStringAsync("https://api.binance.com/api/v1/ticker/price?symbol=DOGEBUSD")
    Await dogebusdTask
    Dim d = JsonConvert.DeserializeObject(Of Dictionary(Of String, String))(dogebusdTask.Result)
    If Decimal.TryParse(d("price"), NumberStyles.Number, CultureInfo.InvariantCulture, price) Then
        _timer.Start()
    End If
End Sub
jxct1oxe

jxct1oxe1#

一个示例,使用.NET 6+ awaitable PeriodicTimerSystem.Text.Json解析由HttpClient的GetStreamAsync()返回的结果流
PeriodicTimer在这样的上下文中非常有效,因为它试图跟上您提供的时间间隔。由于内部过程需要时间来执行(HttpClient.GetStreamAsync()需要不确定的时间来执行并返回结果),因此Timer跟踪实际经过的时间,并试图保持稳定的计时(当然,除非程序所用时间超过指定的间隔,否则您将 * 跳过一个心跳 *)

  • 注意:通常,在处理接受CancellationToken的任务时,您应该在没有调试器(CTRL+F5)的情况下运行此代码,或者将调试器配置为在TaskCanceledExceptionOperationCanceledException时不停止,否则它会在您之前处理(可忽略的)异常
Imports System.Globalization
Imports System.Net.Http
Imports System.Text.Json
Imports System.Threading

Private Shared ReadOnly m_Client As New HttpClient()
Private timerCts As CancellationTokenSource = Nothing
Private m_PeriodicTimer As PeriodicTimer = Nothing
Private m_PeriodicTimerInterval As Integer = 500
Private currentPrice As Decimal = 0.0D

Private Async Function StartPriceLookupTimer(token As CancellationToken, timerInterval As Integer) As Task
    If token.IsCancellationRequested Then Return
    Dim lookupAddress = "https://api.binance.com/api/v1/ticker/price?symbol=DOGEBUSD"
    m_PeriodicTimer = New PeriodicTimer(TimeSpan.FromMilliseconds(timerInterval))
    Try
        While Await m_PeriodicTimer.WaitForNextTickAsync(token)
            Dim jsonStream = Await m_Client.GetStreamAsync(lookupAddress, token)
            Try
                Dim prop = (Await JsonDocument.ParseAsync(jsonStream, Nothing, token)).RootElement.GetProperty("price")
                Dim strPrice = prop.GetString()
                If Decimal.TryParse(strPrice, CultureInfo.InvariantCulture, currentPrice) Then
                ' Do whatever you need to do with the parsed value
                ' E.g., assign it to a TextBox for presentation, 
                ' using the current Culture format, since strPrice contains the original format
                    [Some TextBox].Text = currentPrice.ToString() ' <= UI Thread here
                End If
            Catch knfex As KeyNotFoundException
                Debug.WriteLine("The JSON property was not found")
            Catch tcex As TaskCanceledException
                Debug.WriteLine("The lookup procedure was canceled")
            End Try
        End While
    Catch tcex As TaskCanceledException
        Debug.WriteLine("The lookup procedure was canceled")
    End Try
End Function

Private Sub StopPriceLookupTimer()
    timerCts?.Cancel()
    m_PeriodicTimer?.Dispose()
    timerCts?.Dispose()
    timerCts = Nothing
End Sub

如何启动这个查找过程,调用StartPriceLookupTimer()方法?
您可以使用Button,使其Click处理程序异步:

Private Async Sub SomeButton_Click(sender As Object, e As EventArgs) Handles SomeButton.Click
    If timerCts Is Nothing Then
        timerCts = New CancellationTokenSource()
        Await StartPriceLookupTimer(timerCts.Token, m_PeriodicTimerInterval)
    Else
        Debug.WriteLine("Lookup Timer already started")
    End If
End Sub

或者让表单的Shown Handler /OnShown()方法覆盖async,并在表单首次显示时启动该过程:

Protected Overrides Async Sub OnShown(e As EventArgs)
    MyBase.OnShown(e)
    timerCts = New CancellationTokenSource()
    Await StartPriceLookupTimer(timerCts.Token, m_PeriodicTimerInterval)
End Sub

要停止查找过程,请在需要时调用StopPriceLookupTimer()方法,例如,使用另一个Button或在Form.Closed处理程序/OnFormClosed()覆盖中

相关问题