我有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语句,它将按下单按钮上的所有视频。但我想运行线程所在的特定视频..
请帮助我们
答案 0 :(得分:4)
ThreadState是一个bitmask类型的属性(enum有[Flags]属性,它始终是提示),所以你不要使用==直接检查它,你只需要检查相关位:
if ((t.ThreadState & ThreadState.Running) == ThreadState.Running) { ...
阅读here有关ThreadState值的含义。从阅读那篇文章,或者整篇文章,或整本书(强烈推荐!),你也很可能会注意到你的可能不是理想的方法。 虽然不知道你的确切结局,但很难建议一个确切的结局。
答案 1 :(得分:1)
至于为什么你得到一个例外,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
课程,您甚至可能想要制作该课程的Thread
和string
值字段。
您甚至可能希望在这个新对象的类型按钮上创建一个字段,因此每个按钮都会与一个按钮相关联。
这是面向对象设计的典型特征。没有理由你应该维护四个相同大小的数组,每个数组都有不同的类型。
答案 2 :(得分:0)
@tar 的回答给出了一些提示,但代码是错误的(如@Sampath 所评论)。
这是因为 ThreadState
以一种可疑的奇怪方式实现:
通常位掩码状态使用例如状态 on
的位 1 和
相反 off
的相同位。事实并非如此,事实上,例如,Running
state 的值为 0,而 StopRequested
取值为 1。
所以做一点检查是不明智的。
第一种方法是使用 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();