如何从UWP应用程序(vb.net)中的后台任务在主UI线程上引发事件
我试图从UWP类库后台任务引发一个事件,但我需要在我计划使用类库的UWP应用程序的主UI线程上封送它。不过,我正在寻找一种从后台任务中将其封送的方法。我浏览了几篇文章,包括这篇: 但这对我来说毫无意义。有人能帮我写下面的代码吗如何从UWP应用程序(vb.net)中的后台任务在主UI线程上引发事件,vb.net,uwp,task,Vb.net,Uwp,Task,我试图从UWP类库后台任务引发一个事件,但我需要在我计划使用类库的UWP应用程序的主UI线程上封送它。不过,我正在寻找一种从后台任务中将其封送的方法。我浏览了几篇文章,包括这篇: 但这对我来说毫无意义。有人能帮我写下面的代码吗 Private ReceiveTask As New Task(Sub() Dim InStream As Stream = CSocket.InputStream.AsStreamF
Private ReceiveTask As New Task(Sub()
Dim InStream As Stream = CSocket.InputStream.AsStreamForRead
While killswitch = False
Try
Dim Reader As StreamReader = New StreamReader(InStream)
Dim DataText As String = ""
While Reader.Peek <> -1
DataText &= Convert.ToChar(Reader.Read)
End While
RaiseEvent DataReceived(DataText)
Catch ex As Exception
RaiseEvent SocketError("Receiving", ex.Message)
End Try
End While
End Sub)
Private ReceiveTask作为新任务(Sub()
作为流的Dim流入=CSocket.InputStream.AsStreamForRead
而killswitch=False
尝试
作为StreamReader的Dim读卡器=新StreamReader(流内)
Dim DataText As String=“”
而Reader.Peek-1
DataText&=Convert.ToChar(Reader.Read)
结束时
已接收RaiseEvent数据(DataText)
特例
RaiseEvent插座错误(“接收”,例如消息)
结束尝试
结束时
末端接头)
感谢jmcilhinney,下面的代码可以工作
Private ReceiveTask As New Task(Sub()
Dim InStream As Stream = CSocket.InputStream.AsStreamForRead
While killswitch = False
Try
Dim Reader As StreamReader = New StreamReader(InStream)
If Reader.Peek <> -1 Then
DataText = ""
While Reader.Peek <> -1
DataText &= Convert.ToChar(Reader.Read)
End While
uiContext.Post(AddressOf RaiseDataToUI, Nothing)
End If
Catch ex As Exception
ReceiveError = ex.Message
uiContext.Post(AddressOf RaiseErrorToUI, Nothing)
End Try
End While
End Sub)
Private ReceiveTask作为新任务(Sub()
作为流的Dim流入=CSocket.InputStream.AsStreamForRead
而killswitch=False
尝试
作为StreamReader的Dim读卡器=新StreamReader(流内)
如果Reader.Peek-1那么
DataText=“”
而Reader.Peek-1
DataText&=Convert.ToChar(Reader.Read)
结束时
uiContext.Post(地址为RaiseDataToUI,无任何内容)
如果结束
特例
ReceiveError=ex.Message
uiContext.Post(RaiseErrorToUI的地址,无)
结束尝试
结束时
末端接头)
我自己没有做过任何UWP开发,但我相信正确的方法是使用同步上下文,就像在WPF中一样。其原理是,SynchronizationContext.Current
属性将生成类的特定于线程的实例,因此您可以在UI线程上获取该属性的值,然后在其他地方使用该对象封送对所属线程的调用。属性值通常在UI线程上创建的对象的构造函数中检索,例如
Imports System.Threading
Public Class SomeClass
'Get the context for the thread on which the current instance is created.
Private uiContext As SynchronizationContext = SynchronizationContext.Current
Private Sub ThisMethodIsCalledOnASecondaryThread()
uiContext.Post(AddressOf ThisMethodIsCalledOnTheUIThread, Nothing)
End Sub
Private Sub ThisMethodIsCalledOnTheUIThread(data As Object)
'Execute UI thread logic here, e.g. raise an event.
End Sub
End Class
从某种意义上说,我现在可以将事件提升到UI。但是我已经用测试服务器软件测试了我的测试客户机,看起来uiContext.post无法足够快地将信息发送到UI。我从插座里漏掉了一大堆信息。任务。延迟似乎毫无帮助。有什么想法吗?没关系,它很管用。在事件触发之前正在清除缓冲区。将为其他人发布正确的代码。在上面的示例中,我已将Nothing
传递给post
方法的第二个参数。我看到您在最终代码中也做了同样的操作,这表明您必须在raiseerrotoui
方法中读取数据。您最好在调用Post
并将其传递给该参数之前读取该数据。然后,您将收到它作为您调用的方法顶部的参数。这意味着,在此期间,数据的原始源发生了什么都无关紧要。好主意,我已经实现了,谢谢提示!)