1

ここで賢明な頭に軽く非難されたので、 MessageBox.Show() への呼び出しを、後でファイルに保存される StringBuilder への行の書き込みに切り替えました。どちらもアプリのカスタム例外ハンドラーからです。

public static void ExceptionHandler(Exception ex, string location)
{
    try
    {
        if (inDebugMode)
        {
            LogMsgs.Append(string.Format("{0}\r\n", ex.Message)); 
            DateTime dt = DateTime.Now;
            string timeAsStr = string.Format("{0}_{1}_{2}_{3}.txt", dt.Hour, dt.Minute, dt.Second, dt.Millisecond);
            using (StreamWriter file = new StreamWriter(timeAsStr))
            {
                // If the app crashes, this is how the file is written; if it doesn't, it's written
                // in frmCentral.Form1_Closing()
                file.WriteLine(LogMsgs.ToString());
            }
        }
        MessageBox.Show("Exception: " + ex.Message + "\n\nLocation: " + location, GetFormTitle("CCR: " + ex.GetType().FullName,"",""));
    }

(...これは次のように呼び出されます:

catch (Exception ex )
{
    CCR.ExceptionHandler(ex, "WriteXML.WriteFile");
    . . .

) ...そしてメインフォームの Closed() イベントから:

private void frmCentral_Closed(object sender, EventArgs e)
{
    if (CCR.inDebugMode)
    {
        DateTime dt = DateTime.Now;
        string timeAsStr = string.Format("{0}_{1}_{2}_{3}.txt", dt.Hour, dt.Minute, dt.Second, dt.Millisecond);
        using (StreamWriter file = new StreamWriter(timeAsStr))
        {
            // If the app closes normally, this is how the file is written; if it doesn't, 
            // (it crashed) it's written in PDAClient.ExceptionHandler()
            file.WriteLine(CCR.LogMsgs.ToString());
        }
    }
} // frmCentral_Closed

これは、今日までうまく機能していました。私はそのコードを変更しませんでした。しかし、コードがクラッシュするかどうかに関係なく (メイン フォームから閉じることができます)、ファイルは書き込まれません (少なくとも、以前に書き込まれた場所、つまりハンドヘルド デバイスのルートには書き込まれません)。

私はそのようなメッセージを追加しています:

CCR.LogMsgs.Append(string.Format("DBCommand exception: {0}\r\n", ex.Message));

..そして inDebugMode ブール値は実際に true に設定され、どこにも false に設定されていません。

public static bool inDebugMode = true; //TODO: Change this to false before deploying.

この悪意のある省略の原因は何ですか?

アップデート

jp2codeに答えるには:

これは、キャッチ ブロックで ExceptionHandler が行うことです。

catch(Exception exc)
{
    MessageBox.Show("Exception Handler generated an exception!\n" + exc.Message + "\n\nCalling Location: " + location, GetFormTitle("CCR: " + exc.GetType().FullName,"",""));
}

私がこのコードを書いたわけではないので、多くの場合 (通常は?) その背後にある動機や考え方を知らないことに注意してください。私にはイタリアンフェストよりもスパゲッティに思えますが、たぶん私はそれを理解していないだけです.

多くのものは、コードに表示されるものではありません。たとえば、bool 関数であるかのように名前が付けられた void 関数や、グローバル/キャッチであるとあなたが考える (私はそうするでしょう) ExceptionHandler() メソッドなどです。すべての例外ハンドラーですが、実際にはコード全体で catch ブロックから明示的に呼び出して実行する必要があります。

また、errHndlrLock コードを実装しようとしましたが、コンパイル エラー メッセージ「非静的フィールド、メソッド、またはプロパティ 'PDAClient.SSCS.errHndlrLock' にはオブジェクト参照が必要です」が表示されます。

更新 2

今日は仕事に戻りました。メモリの問題か、それに似た問題だったに違いありません。昨日、休むことなくウォーム ブートを実行しましたが。つまり、機能しましたが、突然機能しなくなり、突然(一晩で)再び機能し始めました。

更新 3

これは、信じられないほど不可解に消えたデバッグ ログ テキスト ファイルの場合に何が起こったのかの手がかりだと思います。今日最新のものを開いたとき、それらはぎっしり詰まっています:

StackOverflowException
StackOverflowException
StackOverflowException
StackOverflowException
StackOverflowException
StackOverflowException
StackOverflowException

...それで十分で、シバン全体が休暇を取ることに決めたと思います。しかし、今はまた休止中です - この CE ジャズは私の祖母のパイ生地よりも薄っぺらです。

4

2 に答える 2

2

Flushナットはそのコールで何かに夢中になる可能性があります。私は彼に+1を与えました。

(私が遭遇した) 発生する可能性があるもう 1 つのことは、一度に複数のアイテムが例外ハンドラーにアクセスしようとすることです。

フォームを閉じようとしていて、メソッドの 1 つで例外がキャッチされているとします。これで、一度に 2 つのルーチンがtimeAsStrファイルにアクセスしようとしていますが、これはあり得ません。

その解決策はlock、例外ハンドラ ルーチンに a を追加することです。

private object errHndlrLock = new Object();

public void ExceptionHandler(Exception ex, string location) {
  lock (errHndlrLock) {
    // continue with your code
  }
}

頭に浮かぶもう 1 つのこと: Exception Handler コードがtry/catchブロックの一部を示していることがわかります。

Q. キャッチした例外はどうするのですか?

同じメソッドを再帰的に呼び出すと、情報が失われる可能性があります。

別のアプローチを取りたい場合はQueue、クラスに対してグローバルに定義された を、次のように使用できますStreamWriter

class CCR {

  private Queue<string> m_queue;
  private StreamWriter m_writer;

  public CCR() {
    m_queue = new Queue<string>();
    m_writer = new StreamWriter(string.Format("Log_{0}.txt", DateTime.Now.ToFileTime()));
  }

  public void ExceptionHandler(Exception ex, string location) {
    string item = string.Format("{0:u}: {1}\r\n\t\t{2}", DateTime.Now, location, ex.Message);
    if (ex.InnerException == null) {
      m_queue.Enqueue(item);
    } else {
      m_queue.Enqueue(item + string.Format("\r\n\t\tInner Exception: {0}", ex.InnerException.Message));
    }
    QueueHandler();
  }

  private void QueueHandler() {
    while (0 < m_queue.Count) {
      m_writer.WriteLine(m_queue.Dequeue());
    }
  }

  public void Close() {
    QueueHandler();
    m_writer.Flush();
    m_writer.Close();
    m_writer.Dispose();
  }

Close()コードが終了する前に必ず呼び出してください

于 2013-03-28T14:50:10.453 に答える
2

私は間違っているかもしれませんが、ストリーム バッファがフラッシュされていないようです。

追加してみる

file.Flush();

writeline への呼び出しの後。また、ストリームを明示的に閉じる場所も見当たりません。そうすることをお勧めします。

于 2013-03-27T21:53:27.937 に答える