C# 如何检查线程的状态

C# 如何检查线程的状态,c#,.net,multithreading,C#,.net,Multithreading,我有一个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;

我有一个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();
                        }
                    }
                }
            }      
    }
publicstring[,]vpath=新字符串[3,7];
公共视频[,]视频=新视频[3,7];
公共静态线程[,]th=新线程[3,7];
public void playclick(对象发送者,事件参数e)
{
int i,j;

对于(j=0;jThreadState是位掩码类型属性(enum具有[Flags]属性,这始终是提示),因此您不需要使用==直接检查它,只需要检查相关位:

if ((t.ThreadState & ThreadState.Running) == ThreadState.Running) { ...
阅读ThreadState值的含义。通过阅读这篇文章,或者整本书(强烈推荐!),你很可能会注意到你的方法可能不是理想的方法。
虽然不知道你的确切结局,但很难给出一个确切的结局。

至于为什么会出现异常,HaemEternal在他的评论中明确指出了这一点。你一次只初始化一个线程,但你正在检查所有线程。
null
thread对象没有
ThreadState

不过,我可以建议你完全改变你的设计吗; 无需经常检查哪个线程被激活。您可以更改
Play()
方法的签名以接受
对象
,并且可以使用该
对象
将正确的视频传递给该方法

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();
    }        
}
public void playclick(对象发送方,事件参数e)
{
int i,j;

对于(j=0;j,@tar的答案给出了一些提示,但代码是错误的(正如@Sampath所评论的)

这是因为
ThreadState
是以一种奇怪的方式实现的: 通常情况下,位掩码状态是使用状态
on
的位1和 相反的
关闭时使用相同的位。事实并非如此,例如,正在运行的

状态值为0,而1值由
StopRequested
获取

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

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

while(t.ThreadState==ThreadState.Running||
t、 ThreadState==ThreadState.Background)
Application.DoEvents();
t、 Join();
请记住,如果您在后台启动一个流程,您将拥有
ThreadState.Background
enum值返回,而不是
ThreadState.Running
, 这就是为什么我把两者都放在这里

更好、更简单的方法是:

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

不是第一次通过初始化线程的循环调用play(),它将通过所有线程循环,但您只初始化了第一个线程吗?play()函数是否应该不仅仅处理从中调用它的线程?这是哪个视频类?play真的是同步的(模态的)?仅当按下btnp(多个按钮中的一个动态按钮)时,才会创建线程…然后播放()将被调用。但是如果我不检查线程的状态,那么我所有的视频都将只使用一个我不想要的按钮开始播放。因此我正在检查那里的状态。但是我在检查时遇到了一个异常。这有点愚蠢。只需将正确的视频传递给播放方法。感谢ans@Tar,但我仍然得到了EXECoption…if((th[i,j].ThreadState&ThreadState.Running)==ThreadState.Running){..}异常是:NULL引用异常未处理。我只是说线程的2dim数组。如果初始化整个矩阵(没有if(…捕获))很抱歉,这是最基本的东西,如果你在这方面有问题,你绝对不应该尝试使用线程。如果不使用if(btnp[I,j].Capture))然后我将如何检查按下了哪个按钮bcoz正如我之前所说,我有多个动态创建的BTN…我想你缺少了动态按钮的基本概念…但是感谢这篇文章,感谢你尝试帮助meso在play()方法中添加另一个检查,在该方法中,你检查[i,j]==null。在任何情况下,请接受答案。这将始终返回true。线程状态“正在运行”为0,运行的操作始终返回0,这是“正在运行”状态。不工作,先生,我在th[I,j]处遇到异常。开始(视频[I,j]);在Video vid=Video as Video时出错;操作异常无效:线程是使用不接受参数的ThreadStart委托创建的。奇数,对我有效。请尝试使用
th[i,j]=新线程(新参数化ThreadStart(播放));
而不是当前构造函数。听起来好像您没有更改什么。如果您指的是
video
为空的错误。您初始化了它吗?