【问题标题】:How do I check the state of a thread如何检查线程的状态
【发布时间】:2012-09-12 07:12:36
【问题描述】:

我有一个 winform 应用程序,我正在尝试播放多个视频,我正在为此创建线程。我的代码是:

public String[,] vpath = new String[3, 7]; 
public Video[,] video = new Video[3, 7];
public static Thread[,] th = new Thread[3, 7];

public void playclick(object sender, EventArgs e)
    {
        int i, j;

        for (j = 0; j <= 7 - 1; j++)
        {
            for (i = 0; i <= 3 - 1; i++)
            {
                if (btnp[i, j].Capture)
                {
                    //play();

                    th[i, j] = new Thread(new ThreadStart(play));
                    th[i, j].IsBackground = true;
                    th[i, j].Start();
                }
            }
        }

    }

 public void play()
    {

            int i, j;
            for (j = 0; j <= 7 - 1; j++)
            {
                for (i = 0; i <= 3 - 1; i++)
                {
                    if (th[i, j].ThreadState == ThreadState.Running) // Having problem here
                    {
                        if (video[i, j].State != StateFlags.Running)
                        {
                            video[i, j].Play();
                        }
                    }
                }
            }      
    }

因此,如果没有该 if 语句,它将在单键按下时运行所有视频。但我想运行线程所在的特定视频..

请帮帮我

【问题讨论】:

  • 难道不是第一次通过初始化线程的循环,会调用pl​​ay(),它会循环遍历所有线程,但你只是初始化了第一? play() 函数不应该只处理调用它的线程吗?
  • 这是哪个视频类? Play 真的是同步的(模态的)吗?
  • 只有当 btnp(一个动态按钮之一)被按下时才会创建线程......然后将调用 play()。
  • 但是如果我不检查线程的状态,那么我所有的视频都将开始播放只有一个我不想要的按钮......所以我正在检查那里的状态......但我我在检查中遇到了异常
  • 这有点傻。只需将正确的视频传递给播放方法即可。

标签: c# .net multithreading


【解决方案1】:

ThreadState是位掩码类型的属性(枚举有[Flags]属性,一直是提示),所以不用==直接检查,只需要检查相关位即可:

if ((t.ThreadState & ThreadState.Running) == ThreadState.Running) { ...

阅读here 了解 ThreadState 值的含义。通过阅读该文章以及可能的整篇文章或整本书(强烈推荐!),您也很可能会注意到您的方法可能不是理想的方法。 虽然不知道你的确切结局,但很难建议一个确切的结局。

【讨论】:

  • 感谢@Tar 的回答,但我仍然遇到异常... if ((th[i, j].ThreadState & ThreadState.Running) == ThreadState.Running){..}异常是:NULL Reference Exception was unhandled
  • 好吧,我只是在谈论 2dim 线程数组。如果您初始化整个矩阵(没有 if (...Capture)),那么您将不会得到 NullRef 异常。很抱歉,这是最基本的东西,如果你遇到问题,你绝对不应该尝试使用线程。
  • 如果不使用 if(btnp[i,j].Capture)) 那么我将如何检查按下了哪个按钮 bcoz 正如我之前所说的我有多个动态创建的 btns .. . 我认为您缺少基本概念动态按钮...但感谢您的文章并感谢您尝试帮助我
  • 所以在 play() 方法中添加另一个检查,检查 th[i, j] == null。无论如何,请接受答案。
  • 这将始终返回 true。线程状态“正在运行”为 0,运行中的操作总是返回 0,即“正在运行”状态。
【解决方案2】:

至于为什么你会得到一个例外,HaemEternal 在他的评论中指出了这一点。您一次只初始化一个线程,但您正在检查所有线程。 null 线程对象没有 ThreadState 值。

我可以建议您完全改变您的设计吗? 无需不断检查激活了哪个线程。您可以更改Play() 方法的签名以接受Object,并且可以使用Object 将正确的视频传递给方法。

public void playclick(object sender, EventArgs e)
{
    int i, j;

    for (j = 0; j <= 7 - 1; j++)
    {
        for (i = 0; i <= 3 - 1; i++)
        {
            if (btnp[i, j].Capture)
            {
                //play();

                th[i, j] = new Thread(new ParameterizedThreadStart(play));
                th[i, j].IsBackground = true;
                th[i, j].Start(video[i,j]);
            }
        }
    }

}

public void play(object video)
{
    Video vid = video as Video; 
    if (vid.State != StateFlags.Running)
    {
        vid.Play();
    }        
}

更好的方法是将这三个元素封装在一个对象中,该对象包含一个Video 对象、一个Thread 对象和一个路径string

如果您拥有Video 类,您甚至可能想要创建该类的Threadstring 值字段。 你甚至可能想在你的按钮上创建一个新对象类型的字段,这样每个按钮都将与一个按钮相关联。 这在面向对象设计中更为典型。没有理由你应该维护四个独立的大小相同的数组,每个数组都有不同的类型。

【讨论】:

  • 不工作先生,我在 th[i,j].Start(video[i,j]); Video vid = video as Video;
  • 无效操作异常:线程是使用不接受参数的 ThreadStart 委托创建的。
  • 奇怪,对我有用。尝试使用 th[i, j] = new Thread(new ParameterizedThreadStart(play)); 而不是当前的构造函数。
  • 听起来好像你没有改变什么。
  • 如果你指的是video为null的错误..你初始化了吗?
【解决方案3】:

@tar 的回答给出了一些提示,但代码是错误的(正如 @Sampath 所评论的那样)。

这是因为ThreadState 是以一种可疑的奇怪方式实现的: 通常,位掩码状态使用例如状态on 的位1 和 相反的off 的位相同。其实不是这样的,比如Running state 的值为 0,而 1 的值由 StopRequested 获取。

所以做一点检查是不明智的。

第一种方法是使用 or 语句检查状态:

while (t.ThreadState == ThreadState.Running ||
    t.ThreadState == ThreadState.Background)
    Application.DoEvents();
t.Join();

请记住,如果您在后台启动一个进程,您将拥有 ThreadState.Background 返回枚举值而不是 ThreadState.Running, 这就是为什么我把两者都放了。

更好更简单的方法是:

while (t.IsAlive)
    Application.DoEvents();
t.Join();

【讨论】:

    猜你喜欢
    • 2010-11-08
    • 1970-01-01
    • 1970-01-01
    • 2020-06-30
    • 1970-01-01
    • 2011-07-17
    • 2015-04-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多