2017-04-11 72 views
-1

我正在尋找一種方式來調用在不同線程上的函數跨線程調用(c#,WaveEngine)

我們正在使用一個服務器(gRPC),它在接收到數據時發送數據,一個任務在客戶端運行,一旦接收到新數據就會繼續循環(stream.MoveNext())。

一旦接收到新的數據將調用一個函數,雖然這是一個不同的線程中完成

注:我沒有得到Cross-Thread Exception,這是因爲它的構建和測試開發機上是禁用期間不可能。

public static async Task ButtonStream() 
{ 

    var rpc = buttonClient.buttonPressed(new ButtonsSubscription()); 
    try 
    { 
     using (rpc) 
     { 
      var stream = rpc.ResponseStream; 
      while (await stream.MoveNext()) 
      { 
       if (stream.Current.Id >= persistantDic.Count) 
       { 
        int a = stream.Current.Id; 
        int b = persistantDic.Count; 

        //Console.WriteLine("{0} >= {1}", a,b); 
        throw new Exception("Something went wrong"); 
       } 
       else 
       { 
        buttonPressed = stream.Current.Id; 
        gRPCEvents.ButtonUpdates?.Invoke(); 
        Console.WriteLine("Invoked from thread: "+Thread.CurrentThread.ManagedThreadId); 
       } 
      } 
     } 
    } 
    catch (RpcException e) 
    { 
     throw; 
    } 
} 

ButtonUpdates?.Invoke運行中的主要功能(線程ID 1),當我按下F1(僅適用於測試目的),我看到它的運行對線程1的功能,但是當它被調用的線程4(其運行功能或9,有時會改變)。

編輯

在主線程功能是訂閱調用的委託,這將是一個任務調用上線4

+3

那麼你的問題是什麼? –

+0

在不同的線程中調用這些函數的方式是什麼 – Maxdg

+1

當你使用'async'時,你*不需要調用。 –

回答

0

解決,只計算邏輯/遠程調用,

WaveEngine給我提供了一個簡單的解決方案來連接他們的主線程

WaveServices.Dispatcher.RunOnWaveThread(() => 
{ 
    //Any code here for execution 
}); 
+0

你在Wave線程中執行了哪些操作,它是否允許UI控制更新 –

+0

@MrinalKamboj在wavethread上,我更改紋理併爲其周圍添加動畫。 – Maxdg

0

這裏有兩個要點:

  1. gRPCEvents.ButtonUpdates?.Invoke(),總是意味着在主/ UI線程上工作
  2. 此代碼的位置不正確Console.WriteLine("Invoked from thread: "+Thread.CurrentThread.ManagedThreadId);,因爲它是一個主線/ Ui線程,無論顯示哪個數字,都會不斷變化。你想把它使用調用的函數裏面MethodInvoker delegate

什麼在我的理解你的要求是,如何執行一個單獨的線程的更新功能,但你會需要的是自由的UI線程來執行其它功能同時,可能的選項是:

  1. Task<T>.Run(Func<T> function),但是當你等待任務完成時,它仍然會阻塞主線程。
  2. 執行並調用Async版本,該版本可以使用TaskCompletionSource,現在這將有助於切回UI線程以使UI更具功能性並且完成後UI控制可以無縫無縫地更新,因爲這就是它的意圖去做。
  3. 你可能會被包裹裏面Task<T>你的方法並等待它,但是異步封裝在一個同步方法不是一個好的做法

EDIT1

記住,如果我不明白,UI控制永遠無法更新任何其他線程比主線程在另一個線程