1

いくつかのイベントを永久に追跡するwhileループを実行しています。例外が発生した場合は、現在のスレッドが中止され、そのスレッドの新しい参照が作成されることを期待して、参照をnullに変更しています。現在のスレッドを中止して新しいスレッドを開始するのは正しいですか、それともより良い方法ですか。

私はこれをやろうとしています:

Thread th;

Main()
{
    th = new thread(myfunction);
    th.Start();
}

void myfunction()
{
    while(true)
    {
        try
        {
            // something interesting here.
        }
        catch(exception)
        {
            th = null;
        }
    }
}
4

4 に答える 4

1

そのスレッドに必要なものをすべてクリーンアップしてから、次のように while ループから抜け出します。

void runningOnThread()
{
    while (true)
    {
        try
        {
            //...
        }
        catch (Exception e)
        {
            break;
        }
    }

    //thread cleanup code goes here, if you have any.
}

例外をキャッチしたらログに記録することをお勧めします。そうすれば、いつ例外に遭遇したかがわかります。

于 2012-05-11T05:07:31.940 に答える
1

発生する唯一のことは、スレッドがエンクロージング クラスからアクセスできないままになることです。

それ以上の処理がない場合、そうするとスレッドは GCアプリケーション ルートから到達できなくなります。これにより、オブジェクトは次の GC トリガーでガベージ コレクションに使用できるようになります。

于 2012-05-11T05:08:16.253 に答える
1

あなたがする必要があります:

return;

それ以外の:

th = null;

スレッドが実行され続けるためです。スレッド オブジェクトは、コードが実行されている限り参照され続けるため、収集されません。

于 2012-05-11T05:08:54.403 に答える
1

まず、例外が発生した場合は、新しいスレッドの開始について心配する前に、実際に例外を処理し、再起動されたスレッドが正常に実行できることを確認してください。そうしないと、クラッシュするスレッドの絶え間ないストリームと、例外のパレードを処理している間、途切れ途切れのプログラムを取得することになります。ちょっと考えさせられます。

さて、質問に答えると、最良の場合、スレッドへの参照を null にすると、無限ループに陥ります。最悪の場合、後で「th」を使用しようとすると、null であるため例外が発生します。スレッドへの参照を null にしても、関数の引数として指定したパラメーターへの参照を null にする以上に、スレッド自体を再起動する必要があることを認識させることはできません。スレッドを中止/再起動する何らかの機能がどうしても必要な場合は、次のいずれかを検討してください。

  1. スレッドがクラッシュして while ループから抜け出したときにイベントを発生させる、または
  2. スレッドが何をしているかを示すブール値/列挙型フラグを設定し、メインスレッドに頻繁にチェックさせて、エラー状態に設定されていないことを確認します。

これは私の頭の中から完全に外れているコードです。それほど良くはありませんが、一般的なアイデアを提供します。

delegate void ThreadCrashedEvent();
Event ThreadCrashedEvent threadCrashed;

Thread th;

Main()
{
    threadCrashed += OnThreadCrashed();
    th = new thread(myfunction);
    th.Start();
}

void OnThreadCrashed()
{
    th = new thread(myfunction);
    th.Start();
}

void myfunction()
{
    while(true)
    {
      try
      {
          LetsGetDangerous();
      }
      catch(exception)
      {
          if(threadCrashed != null)
          {
              threadCrashed();
              return;
          }
      }
}
于 2012-05-11T05:21:05.753 に答える