【问题标题】:Detecting a Thread is already running in C# .net?检测线程是否已在 C# .net 中运行?
【发布时间】:2012-10-18 07:12:16
【问题描述】:

我正在使用以下代码。

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() 函数,但我希望线程仅在线程未运行时启动。怎么可能?

【问题讨论】:

  • 你只在运行线程方法中创建线程吗?如果是这样,请将其作为会员并询问 t.IsAlive 还是我错过了什么?

标签: c# .net


【解决方案1】:

GetProcessesByName 不会在您的应用程序中查找线程,而是在您的机器中查找进程。事实上,在你自己的应用程序中没有很好的方法来查询线程(除了编写调试器之外)。

对于你想要的,你可以创建一个wrapper class for your threads,这样你就可以查询它们是否正在运行。或keep track of the threads yourself by other means

你也可以考虑有一个Lazy<Thread>字段,在需要的时候会被初始化,你可以查询线程是否存活。经过测试Lazy<Thread>不好想法。


源自Simon's answer:

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
}

*:Gotta catch'emall


WajidSegey 是对的。你可以只拥有一个 Thread 字段。请允许我提供示例:

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 方法,则不会有创建多个线程的风险。

【讨论】:

  • 好的,先生,我正在尝试,我会在一段时间后回复。
  • 我正在使用 myPage.aspx 页面,并且每次调用 runThread() 函数时都会收到 thread.IsAlive==false。
  • 这可能是go方法执行时间过短或者thread字段的值对其他线程不可见。我将编辑该替代方案以解决该问题。
【解决方案2】:

一个简单的方法是你可以有一个标志来指示它是否正在运行。如果有一些冲突,你可能不得不使用一些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;
}

【讨论】:

  • 在我的情况下这是不可能的,因为这个函数将从另一个地方调用。
【解决方案3】:

你可以使用Thread.IsAlive来检查prevoius线程是否正在运行。这是给线程状态。你可以把这个检查放在mythread.Start().之前

【讨论】:

  • 下次调用同一个函数时如何获取线程对象?
  • 在拥有运行线程方法的类中将胎面作为成员有什么问题?
【解决方案4】:

你是否只在运行线程方法中创建线程?如果是这样,请将其作为包含 runThread 方法的类的字段并询问 t.IsAlive。

【讨论】:

    【解决方案5】:

    也许这对你有帮助

    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
    }
    

    【讨论】:

    • 一些解释会很好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-27
    相关资源
    最近更新 更多