2011-11-08 3 views
1

これはC#のAutoResetEventです。私は他の答えを読もうとしましたが、意味がありませんし、私のシナリオにも適用できませんでした。私はどんなスレッドアプリケーションも書いていません。ファイルと更新を読み取り/検証する小さなアプリケーションです。 固定長ファイルを読み込み、検証し、有効であれば、データベースにアップロードするためのコードを書くというこの要件があります。他のアクションを実行する前にAutoresetイベントが発生するのを待つ方法はありますか?

私がAutoResetEventで立ち往生するまで、私はすべての作業を完了しました。ここには何が起こっているのですか?データが解析/読み込まれると、C#でフラットファイルチェッカーユーティリティを使用してデータを検証します。だから私は自分のアプリケーションに関数を呼び出しました。ここにスニペットがあります。

private AutoResetEvent do_checks = new AutoResetEvent(false); 
public bool ValidationComplete = false; 

この部分は、初期化コードに行く:

this._files.Validated += new EventHandler<SchemaValidatedEventArgs>(FileSetValidated); 

public bool ValidateFile() 
{ 
    try 
    { 
     RunValidation(); 
     return true; 
    } 
    catch (Exception e) 
    { 
     log.Error("Data Validation failed because :" + e.Message); 
     return false; 
    } 
} 

private void RunValidation() 
{ 
    // Use Flat File Checker user interface to create Schema file. 
    do_checks = _files.RunChecks(); 
    log.Debug("Validation Started"); 
} 

これは、検証プロセス中にasnchronusly呼ばなっている方法です。

public void FileSetValidated(Object sender, SchemaValidatedEventArgs e) 
{ 
    try 
    {     
     ValidationComplete = e.Result; 

     if (IsDataValid) 
     { 
      log.Debug("Data is validated and found to be valid."); 
     } 
     else 
     { 
      log.Debug("Data is validated and found to be Invalid"); 
     } 
    } 
    finally 
    { 
     do_checks.Set(); 
    } 
} 

何が起こっているにも私の前にいることですValidationCompleteに設定された値を取得します。コードの検証が完了していることがチェックされ、デフォルトでfalseに設定されているため、falseを返します。 FileSetValidatedのコードはそれ以降に実行されるため、データベースの更新は行われません。

フラットファイルチェッカーはRunChecksメソッドの戻り変数としてAutoResetEventしか受け入れないため、コードを変更できないためです。

** * ***ここは、私が今* ** * ** * プライベートAutoResetEventのdo_checksやったことです。

public bool ValidateFile() 
    { 

     try 
     { 

      string extFilePath = surveyFile.ExtFilePath; 
      File.Copy(extFilePath, localTempFolder + "ExtractFile.Dat"); 
      RunValidation(); 

      if (!do_checks.WaitOne(TimeSpan.FromSeconds(30))) { 

      // throw new ApplicationException("Validation took more than expected!"); 
      }  

      return true; 
     } 
     catch (Exception e) 
     { 
      log.Error("Data Validation failed because :" + e.Message); 
      return false; 

     } 



    } 


    private void RunValidation() 
    { 
     // Use Flat File Checker user interface to create Schema file. 
     do_checks = _files.RunChecks(); 
     do_checks.WaitOne(); 
     log.Debug("Validation Started"); 


    } 

はまた、私は、検証に関するデータはその一部が実行されますので、少なくとも、イベントハンドラの最初の方に渡される部分を移動しました。これは役に立ちましたが、正しいかどうかはわかりません。

+0

ここに欠けている部分があります。 do_checksイベントを作成していますが、後でRunChecks()が返すものを割り当てて、前に作成したものを上書きします。 RunValidationはAutoResetEventのみを受け付けますが、RunValidationはあなたのものであり、何も受け付けません。 RunChecksは1を返します。 RunChecksが返すものを待つことになっている可能性があります。 –

+0

ありがとう!!! RunChecksがAutoResetイベントを返すのは間違いありません。だから私は様々な場所でこのAutoResetイベントを使用しています。異なる機能でどのように参照するのですか?だから私はそれを割り当てずに定義した後、RunChecksが返すときにそれを割り当てます。あなたはそれが正しいと思いますか? – MadCoder

答えて

1

私はlibにして働いたことはないので、私はちょうどそれをダウンロードしてコードに見えました。

まず、 "500 - 内部サーバーエラー"として既に述べたように、コードの一部が欠落していると思われます.FileSetValidatedメソッドで少なくとも "試してください"。 WaitOneでイベントを待っている場所はありません。

_files.RunChecks()は、この特定のファイルの処理のためにAutoResetEvenを作成しますので、あなたは、自分でdo_checksを作成する必要はありません。したがって、同じフィールドをそのイベントに使用している場合、同時に少数のファイルを処理する必要がある場合は問題が発生します。したがって、処理中にdo_checks.Set()と呼ぶ場合は、途中で処理を停止したくない場合は、その参照をメンバーとして保持する理由が各ファイルごとに個別のイベントを保持してください。終了せずに処理をキャンセルします)。

私はlibのコードで見たよう、あなたはdo_checks.Set(呼び出すべきではありません)処理が行われます一度それは、設定されますので、あなただけ書くことができるので、は、方法をFileSetValidated:

var do_checks = _files.RunChecks(); 
do_checks.WaitOne(); 

助けてもらえば分かります。

UPDATE: 私はdo_checksが処理を開始した後に設定されている理由をundestandするために、今そのLIBをチェックすることはできませんが、私はあなたが次のRunValidationで方法あなたの最初のコードを使用することをお勧めすることができます

private void RunValidation() 
{ 
    do_checks.Reset(); //reset state 
    _files.RunChecks(); //don't store event from the lib 
    log.Debug("Validation Started"); 
    do_checks.WaitOne(); //Wait for FileSetValidated to set this event 
} 
+0

返事をありがとう。私はWaitOneをさまざまな場所に追加しようとしていましたが、うまく動作していないようですので、取り除きました。だから、上記のコードを私のコードに追加すると、検証はランダムに行われます。いつか私は時々私が望むものを得る。だからこれが私のしたことです:宣言されたAutoresetイベント、runchecksで使用され、追加されたwaitone。 runvalidation()内のrevious postsで与えられた答えを追加しました。したがって、Dataが有効かどうかを知っている部分を実行し、非同期的にデータベースを更新するような作業をします。私は正しくそれをやっていることを願っています。ありがとう – MadCoder

+0

** ValidateFile **または** RunValidation **にWaitOneを1つだけ残す必要があります。だからこそ、あなたは 'if(!do_checks.WaitOne(TimeSpan.FromSeconds(30))){' –

+0

}の中でいつでもExceptionを取得します。どちらか一方を取り除くと、プログラムはバリデーションが起こるのを待っていません。今日、いくつかのテストを行い、見てみましょう。再度、感謝します。また、私は両者を答えにしたい。私はそれを行う方法がわかりません。 – MadCoder

0

ValidateFile関数を終了する前に、検証が完了するのを待つ必要があります(AutoResetEventを待機してから)検証結果を返します。

はこのような何かを試してみてください:

public bool ValidateFile() 
{ 
    //try 
    { 
     RunValidation(); 

     //Allocate enough time for the validation to occur but make sure 
     // the application doesn't block if the _files.Validated event doesn't get fired 
     if(!do_checks.WaitOne(TimeSpan.FromSeconds(10))) 
     { 
      throw ApplicationException("Validation took more than expected!"); 
     }    

     return ValidationComplete; 
    } 
    //I would not catch the exception since having an error doesn't mean that the file 
    //is invalid. Catch it upper in the call stack and inform the user that the validation 
    //could not be performed because of the error 
    //catch (Exception e) 
    //{ 
    //  log.Error("Data Validation failed because :" + e.Message); 
    //  return false; 
    //} 
} 
+0

答えをありがとう。今私はこの例を試したので、私は10秒20秒30秒を試しても何時でもこのApplicationExceptionを取得します。しかし私がしたことは、これと以下の両方の答えを組み合わせて書かれたことでした。私はそれを投稿します。しかし、このコードは検証が行われるまで待つコードを与えます。 – MadCoder

関連する問題