3

私は次のコードを使用しています。

public void runThread(){
    if (System.Diagnostics.Process.GetProcessesByName("myThread").Length == 0)
    {
    Thread t = new Thread(new ThreadStart(go));
    t.IsBackground = true;
    t.Name = "myThread";
    t.Start();
    }
    else
    {
      System.Diagnostics.Debug.WriteLine("myThreadis already Running.");
    }   
}
public void go()
{
    //My work goes here
}

runThread()関数を何度も呼び出していますが、スレッドが実行されていないときにのみスレッドを開始したいと思います。どうしてそれは可能ですか?

4

5 に答える 5

6

GetProcessesByNameは、アプリケーション内のスレッドではなく、マシン内のプロセスを検索します。実際、独自のアプリケーションでスレッドのクエリを取得する良い方法はありません(デバッガーの作成は別として)。

必要なものについては、スレッドが実行されているかどうかを照会できるように、スレッドのラッパークラスを作成できます。または、他の方法でスレッドを自分で追跡します

また、必要に応じて初期化されるフィールドがあることを検討することもLazy<Thread>できます。また、スレッドが有効であるかどうかを照会することもできます。テスト後Lazy<Thread>は良い考えではありません。


サイモンの答えから派生:

private int running;

public void runThread()
{
    if (Interlocked.CompareExchange(ref running, 1, 0) == 0)
    {
        Thread t = new Thread
        (
            () =>
            {
                try
                {
                    go();
                }
                catch
                {
                    //Without the catch any exceptions will be unhandled
                    //(Maybe that's what you want, maybe not*)
                }
                finally
                {
                    //Regardless of exceptions, we need this to happen:
                    running = 0;
                }
            }
        );
        t.IsBackground = true;
        t.Name = "myThread";
        t.Start();
    }
    else
    {
        System.Diagnostics.Debug.WriteLine("myThreadis already Running.");
    }   
}

public void go()
{
    //My work goes here
}

*:すべてをキャッチする必要があります


WajidSegeyは正しいです。スレッドフィールドを持つことができます。例を挙げさせてください。

private Thread _thread;

public void runThread()
{
    var thread = _thread;
    //Prevent optimization from not using the local variable
    Thread.MemoryBarrier();
    if
    (
        thread == null ||
        thread.ThreadState == System.Threading.ThreadState.Stopped
    )
    {
        var newThread = new Thread(go);
        newThread.IsBackground = true;
        newThread.Name = "myThread";
        newThread.Start();
        //Prevent optimization from setting the field before calling Start
        Thread.MemoryBarrier();
        _thread = newThread;
    }
    else
    {
        System.Diagnostics.Debug.WriteLine("myThreadis already Running.");
    }
}

public void go()
{
    //My work goes here
}

:スレッドセーフであるため、最初の選択肢(Simonの回答から派生したもの)を使用することをお勧めします。つまり、メソッドrunThreadを同時に呼び出すさまざまなスレッドがある場合、複数のスレッドが作成されるリスクはありません。

于 2012-10-18T07:18:10.477 に答える
2

簡単な方法の1つは、実行されているかどうかを示すフラグを設定できることです。lockそれがいくつかの衝突であるならば、あなたは多分いくつかを使わなければならないでしょう。

public static bool isThreadRunning = false;

public void runThread()
{
    if (!isThreadRunning)
    {
        Thread t = new Thread(new ThreadStart(go));
        t.IsBackground = true;
        t.Name = "myThread";
        t.Start();
    }
    else
    {
      System.Diagnostics.Debug.WriteLine("myThreadis already Running.");
    }   
}
public void go()
{
    isThreadRunning = true;
    //My work goes here
    isThreadRunning = false;
}
于 2012-10-18T07:16:15.847 に答える
1

Thread.IsAliveprevoiusスレッドが実行されているかどうかを確認するために使用できます。これは、スレッドのステータスを示すためです。この確認は、前に行うことができます。mythread.Start().

于 2012-10-18T07:17:54.177 に答える
0

run threadメソッドでのみスレッドを作成しますか?その場合は、runThreadメソッドを保持するクラスのフィールドとして保持し、t.IsAliveに問い合わせます。

于 2012-10-18T07:17:59.867 に答える
0

多分これはあなたを助けることができます

static bool isRunning = false;
public void RunThread(){
    if (!isRunning)
    {
    Thread t = new Thread(()=> { go(); isRunning = true;});
    t.IsBackground = true;
    t.Name = "myThread";
    t.Start();
    }
    else
    {
      System.Diagnostics.Debug.WriteLine("myThread is already Running.");
    }   
}
public void go()
{
    //My work goes here
}
于 2017-06-13T14:11:47.970 に答える