2017-06-09 8 views
0

謝罪私はこの質問にどのようにタイトルを付けるか考えていません。スレッドがアイドルになるまでスレッドを続行できるように、各イタレーションで中断する同期タスクを書き込む方法

ホストアプリケーションのプラグインを作成していますオブジェクトを提供していますが、制約を処理したいのは、これらのオブジェクトをホストメインアプリケーションスレッドだけで処理する必要があることです。私が別のスレッドでそれらに触れると、ホストは死ぬ。

私は状況を示し、私が何をしたいのかをコメントで示しているモックシナリオを書いています。基本的に私は処理するオブジェクトの束を取得します。これらのオブジェクトを一度に1つずつ処理することができるタスクを作成したいと思います。ホストはアイドル状態ですが、各反復でスレッドに制御を渡して、ホストがアイドル状態を更新できるようにします(イベント)ホストがビジーだと言うなら、ホストがアイドル状態に戻るまで処理タスクを中断したままにしておきたい。

私はそれが次のようなコードであると想像しました。しかし、私はこの問題をどのように攻撃するか分からず、Task/Asyncプリンシパルでは可能かどうかもわかりません。

public class MockHost 
{ 
    public event EventHandler Idle; 
    public event EventHandler Busy; 
    public event EventHandler<ModifiedObjectsEventArgs> IHaveModifiedObjectsHereYouGo; 
} 
public class ModifiedObjectsEventArgs: EventArgs 
{ 
    public object[] ModifiedObjects; 
} 
public class TestClass 
{ 
    MockHost _host = new MockHost(); 
    ObjectProcessor _processor = new ObjectProcessor(); 


    public TestClass() 
    { 
     _host.Idle += _host_Idle; 
     _host.Busy += _host_Busy; 
     _host.IHaveModifiedObjectsHereYouGo += _host_IHaveModifiedObjectsHereYouGo; 
    } 

    private async void _host_IHaveModifiedObjectsHereYouGo(object sender, ModifiedObjectsEventArgs e) 
    { 
     await _processor.ProcessObjectsAsync(e.ModifiedObjects); 
    } 

    private void _host_Busy(object sender, EventArgs e) 
    { 
     _processor.SetHostBusyState(true); 
    } 

    private void _host_Idle(object sender, EventArgs e) 
    { 
     _processor.SetHostBusyState(false); 
    } 
} 

public class ObjectProcessor 
{ 
    bool _hostIsBusy = false; 
    public void SetHostBusyState(bool isBusy) 
    { 
     _hostIsBusy = isBusy; 
     if(!_hostIsBusy) 
     { 
      // Continue processing. 
     } 
    } 
    public async Task ProcessObjectsAsync(Object[] objects) 
    { 
     foreach(object obj in objects) 
     { 
      if (_hostIsBusy) 
      { 
       // suspend this task somehow 
      } 
      else 
      { 
       ProcessObject(obj); 
      } 
      // suspend the task somehow to let the host events update busy status if they need to. 
     } 
    } 

    private void ProcessObject(object obj) 
    { 
     // Long running process. 
    } 
} 
+0

UIスレッドで非UI作業を長時間実行するのではなく、しばらく停止してUIイベントを処理させようとするのではなく、UIスレッド*でUI以外の作業をしないでください。 UI以外のスレッドでの非UI作業 – Servy

+0

私は、私が支配権を持っていないホストによって強制される選択肢がありません。私はホストアプリケーションスレッド上のオブジェクトとのみ対話できます。 – John

+0

一時的にホストに制御を戻したい場合は、 'await Task.Yield();'を使うことができます。(ホストが同期コンテキストを設定していると仮定して) –

答えて

1

あなたは使用することで、いつでも戻ってホストに制御を得ることができる:

await Task.Yield(); 

を。これは、ホストが同期コンテキストを設定していることを前提としています。

現在のタスクを終了し、継続を同期コンテキストにポストします。このようにして、ホストはスレッドを取得し、必要なコードを実行してから、コントロールを継承に戻すことができます。

関連する問題