我正在使用電報 API 向客戶端發送訊息。我正在使用的代碼是:
Imports System.Threading
Imports Telegram.Bot
Imports Telegram.Bot.Extensions.Polling
Imports Telegram.Bot.Types
Imports Telegram.Bot.Types.Enums
Public Class form1
Private Async Function HandleUpdateAsync(botClient As ITelegramBotClient,
update As Update,
cancellationToken As CancellationToken) As Task
If update.Message IsNot Nothing Then
If Not String.IsNullOrEmpty(update.Message.Text) Then
Select Case update.Message.Text
Case "/0"
Await botClient.SendTextMessageAsync("chatid", RichTextBox1.Text)
Case "/star2t"
Await botClient.SendTextMessageAsync("chatid", "text")
End Select
End If
End If
End Function
Private Function HandleErrorAsync(botClient As ITelegramBotClient,
exception As Exception,
cancellationToken As CancellationToken) As Task
Console.WriteLine(exception)
Return Task.CompletedTask
End Function
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'invio messaggio
Dim bot = New TelegramBotClient("token id")
Await bot.SendTextMessageAsync("chatid", "Test")
End Sub
Private Sub form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim bot = New TelegramBotClient("My id")
Dim cts = New CancellationTokenSource()
Dim options = New ReceiverOptions With {
.AllowedUpdates = Array.Empty(Of UpdateType)()
}
bot.StartReceiving(updateHandler:=AddressOf HandleUpdateAsync, errorHandler:=AddressOf HandleErrorAsync, options, cts.Token)
Console.ReadLine()
End Sub
End Class
它正在發送訊息
Await botClient.SendTextMessageAsync("chatid", "text")
但它沒有發送它
和
Await botClient.SendTextMessageAsync("chatid", Richtextbox5.text)
我在運行時或除錯時沒有收到任何錯誤,但在除錯時檢查 VS 上的即時視窗我發現存在跨執行緒問題:
exception thrown: 'System.InvalidOperationException' in System.Windows.Forms.dll
System.InvalidOperationException: Cross-thread operation not valid: Control 'RichtextBox5' accessed from a thread other than the thread it was created on
in System.Windows.Forms.Control.get_Handle()
in System.Windows.Forms.RichTextBox.StreamOut(Stream data, Int32 flags, Boolean includeCrLfs)
in System.Windows.Forms.RichTextBox.StreamOut(Int32 flags)
in System.Windows.Forms.RichTextBox.get_Text()
in HotBit_APIs.Form1.VB$StateMachine_17_HandleUpdateAsync.MoveNext()
in C:\Users\Mattia\source\repos\HotBit APIs\HotBit APIs\Form1.vb:line 81
I've been looking online for a solution and I came accross this code
Private Sub UpdateTextBox(text As String)
If TextBox1.InvokeRequired Then
'We are on a secondary thread.
TextBox1.Invoke(New Action(Of String)(AddressOf UpdateTextBox), text)
ecc
or yourForm.Invoke(new Action(() => {GUI code here}))
但我不知道如何用我的代碼實作。關于我如何做到這一點的任何想法?
uj5u.com熱心網友回復:
您不能從任何執行緒訪問 UI 元素 - 它必須在 UI 執行緒上。使用這樣的處理程式,您不能假設您在 UI 執行緒上,實際上您應該假設您可能不在。確保正確訪問 UI 控制元件的方式,始終InvokeRequired在訪問之前檢查是否。
Dim text As String
If control.InvokeRequired Then
control.Invoke(Sub() text = control.Text)
Else
text = control.Text
End If
在您的情況下,問題出在HandleUpdateAsync. 代碼行
Await botClient.SendTextMessageAsync("chatid", RichTextBox1.Text)
可以改為
Dim text As String
If RichTextBox1.InvokeRequired Then
RichTextBox1.Invoke(Sub() text = RichTextBox1.Text)
Else
text = RichTextBox1.Text
End If
Await botClient.SendTextMessageAsync("chatid", text)
公認的方法不是在這樣的代碼中行內。你的谷歌搜索找到了它。一般是這樣的
Private Function GetRichTextBox1Text() As String
If RichTextBox1.InvokeRequired Then
Return RichTextBox1.Invoke(AddressOf GetRichTextBox1Text)
Else
Return RichTextBox1.Text
End If
End Function
Await botClient.SendTextMessageAsync("chatid", GetRichTextBox1Text())
沒有人愿意一直這樣做。您可以在這樣的模塊中撰寫擴展方法(用于操作和簡單功能),當然您可以推斷出任意數量的引數
<Extension(), DebuggerHidden()>
Public Sub InvokeIfRequired(control As Control, action As MethodInvoker)
If control.InvokeRequired Then control.Invoke(action) Else action()
End Sub
' No parameters
<Extension(), DebuggerHidden()>
Public Function InvokeIfRequired(Of TR)(control As Control, func As Func(Of TR)) As TR
If control.InvokeRequired Then
Return control.Invoke(func)
Else
Return func.Invoke()
End If
End Function
' One parameter
<Extension(), DebuggerHidden()>
Public Function InvokeIfRequired(Of T1, TR)(control As Control, func As Func(Of T1, TR), arg1 As T1) As TR
If control.InvokeRequired Then
Return CType(control.Invoke(func, arg1), TR)
Else
Return func.Invoke(arg1)
End If
End Function
' n parameters can be extrapolated...
在您的情況下,請使用該功能
Await botClient.SendTextMessageAsync("chatid", RichTextBox1.InvokeIfRequired(Function() RichTextBox1.Text))
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/437681.html
標籤:VB.net
上一篇:如何排除部分影像[VB.NET]
下一篇:如果我點擊計算按鈕程式崩潰?
