2

私はだから私は私のメインクラスで新しいタスクを作成したデータは、それが入ってくるように、データをキューするDataInCollectionに追加され、私たちは」次のコードのセットアップスレッディングとSOLID原則

public interface ILogger 
{ 
    void WriteData(string Data); 
} 

public class Logger : ILogger 
{ 
    public void WriteData(string Data) 
    { 
    //Write to disk 
    } 
} 

public interface ILogic 
{ 
    void ProcessData(string Data); 
} 

public class Logic : ILogic 
{ 
    private ILogger Logger; 

    public Logic(ILogger Logger) 
    { 
    this.Logger = Logger; 
    } 

    public void ProcessData(string Data) 
    { 
    //Do stuff 
    Logger.WriteData("Data to write"); 
    } 
} 

public class MainEntryPointClass 
{ 
    private BlockingCollection<string> DataInCollection; 
    private Task DataInTask; 
    private CancellationTokenSource CancellationTokenSource; 

    public Start() 
    { 
     InitializeDataIn(); 
    } 

     private void InitializeDataIn() 
     { 
      CancellationTokenSource = new CancellationTokenSource(); 
      DataInCollection = new BlockingCollection<DataInContents>(); 
      DataInTask = Task.Factory.StartNew(() => ProcessDataIn(CancellationTokenSource.Token)); 
     } 

     private void ProcessDataIn(CancellationToken CancelToken) 
     { 
      while (!CancelToken.IsCancellationRequested) 
      { 
       foreach (var item in DataInCollection.GetConsumingEnumerable()) 
       { 
        Logic.ProcessData(item); 
       } 
      } 

     } 
} 

を持っています30ミリ秒ごとに話をする。これは正常に処理されます。

私は今、別のスレッドでファイルにデータを書きたいと思っています。そのため、ディスクに問題がある場合、メインロジックのチェックには影響ありません。ディスクに問題がある場合は、ロジックを続行できます。私は別のスレッドでファイルの書き込みをどこで行うのか分かりません。 Mainクラス、Logicクラス、Loggerクラスのどちらですか?

+0

(私は... IOスレッド、フィールド、複数のロガーの取り扱い、の終了条件のようなものを省いに)悪い...誰かが文章を出すだろう: "なぜ車輪を再発明するか?例えばlog4netを取る" ...本当の基本質問をよりよく指摘する! –

+0

サードパーティの参照が許可されていないため、NLogが別のスレッドで書き込みを行っていると判断できないためです。さまざまなスレッドから呼び出すことができますが、実際に別のスレッドに書き込むかどうかはわかりません。フォーラムの質問を出しましたが、答えはありません。 – Jon

+0

私はまだあなたの基本的な質問を得ていません...それはa)操作が時々例外をスローするときに 'WriteDataToFile'呼び出しを処理する方法b)私の現在のスレッドから' WriteDataToFile'呼び出しを分離する方法私は私の執行で進むことができます...?最終的には、「サードパーティのリファレンスは許されません」...その説明は何ですか? ...合理的なもの?こんにちは!? –

答えて

3

Loggerは、発信者をブロックしないようにする責任があります。それには、さまざまな戦略を使用できます。あなたはそれらの戦略をそれを使用するクラスに焼きたいとは思わない。

私はメッセージをBlockingCollection<T>にエンキューし、1つのIOスレッドでディスクに書き込むようにしました。

Common.Logging's ILogのような既存のロギングインターフェイスを模倣することをお勧めします。「サードパーティなし」の要件がなくなると、既存のログフレームワークに簡単に切り替えることができます。

ような何か:

class AsyncLogger:ILogger 
{ 
    public AsyncLogger(ILogger backingLogger) 
    { 
    new Thread(()=> 
     { 
     while(true) 
     { 
      var data=_queue.Take(); 
      _backingLogger.WriteData(data); 
     } 
     } 
    ).Start(); 
    } 

    public void WriteData(string data) 
    { 
    _queue.Enqueue(data); 
    } 
} 

多分この質問のためのロガー・インプリメンテーションをされて使用して

+0

私が持っているものと非常に似BlockingCollectionとTask? – Jon

+0

キューが使用されておらず、非同期を実行するタスクを起動しただけで問題が発生する場合は、ここの例https://gist.github.com/2235771 – Jon

+0

@Jonこれは注文の問題につながります。また、 'backingLogger'へのアクセスをシリアライズするために手動ロックを追加する必要があります。 – CodesInChaos

1

ロガークラスはロギングを担当します。したがって、受信データをディスクに記録するのに適しているようです。

+0

BlockingCollectionとTaskを使用して同様のデザインにする必要がありますか? – Jon

+0

@ジョン、あなたはあなたが望むものを使うことができます。あなたの 'Logger.WriteData'関数を非同期で動作させてください:データをいくつかのスレッドセーフなコレクションに格納し、別のスレッド/タスクを回転させてください。 – Jan

+0

@Janおかげで、非同期のロジックと次の問題の統合テスト:( – Jon

関連する問題