2017-01-29 5 views
0

UWPクラスライブラリのバックグラウンドタスクからイベントを発生させようとしていますが、メインでマーシャリングする必要がありますUWPアプリのUIスレッド私はクラスライブラリを使用する予定です。私はバックグラウンドタスクからマーシャリングする方法を探しています。私はこの1つを含むいくつかの記事を見てきました: Raise Events in .NET on the main UI thread しかし、それは意味がありません。誰も私の下のコードを助けることができますか?UWP APP(vb.net)のバックグラウンドタスクからメインUIスレッドのイベントを発生させる方法

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)  

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) 

答えて

0

私は、任意のUWPの開発を自分自身を行っていませんでしたが、私はあなたが望むよう行うための正しい方法は、WPFのように、SynchronizationContextクラスを使用することであると信じています。原則として、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 
+0

これは、イベントをUIに呼び出すことができるという意味で機能します。しかし、私はテストサーバーソフトウェアでテストクライアントをテストしました.UiContext.postがUIに十分速く情報を送信できないようです。私はソケットを介して来る情報の束を見逃しています。 Task.Delayはまったく役に立たないようです。何か案は? – Kevin

+0

これは問題ありません。イベントが発生する前にバッファをクリアしていました。他の人のための正しいコードを投稿します。 – Kevin

+0

上記の例では、 'Post'メソッドの第2引数に' Nothing'を渡しました。最終的なコードで同じことを行ったことがわかります。これは、RaiseErrorToUIメソッドでデータを読み込む必要があることを示しています。 'Post'を呼び出す前にそのデータを読み、それをそのパラメータに渡す方が良いでしょう。次に、呼び出すメソッドの先頭に引数として受け取ります。これは、その間にそのデータの元のソースに何が起こっても問題ではないことを意味します。 – jmcilhinney

関連する問題