Reputation: 699
I have winform application where i am trying to play multiple videos and i am creating threading for that. My code is :
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();
}
}
}
}
}
So with out that if statement it will run all the videos on single button press. But i want to run the particular video which the thread is in ..
pls help me guys
Upvotes: 2
Views: 14176
Reputation: 39
if (th.ThreadState.Equals(ThreadState.Unstarted))
th.Start();
Upvotes: 0
Reputation: 2021
The answer by @tar gives some hints but the code is wrong (as commented by @Sampath).
This come from the fact that ThreadState
is implemented in a questionable strange way:
Normally a bitmask state is implemented using for example bit 1 for state on
and the
same bit for the opposite off
. This is not the case, in fact, for example, the Running
state has a 0 value, whereas the 1 value is taken by StopRequested
.
So it is not wise to do a bit check.
A first approach would be to check for state with an or statement:
while (t.ThreadState == ThreadState.Running ||
t.ThreadState == ThreadState.Background)
Application.DoEvents();
t.Join();
Keep in mind that if you start a process in background you will have the
ThreadState.Background
enum value returned and not ThreadState.Running
,
this is why I have put both.
The better and simpler approach is:
while (t.IsAlive)
Application.DoEvents();
t.Join();
Upvotes: 0
Reputation: 21917
As to why you are getting an exception, HaemEternal nailed that in his comment. You are only initializing one thread at a time, yet you are checking all of them. A null
thread object does not have a ThreadState
value.
May I suggest though, that you change your design altogether;
There is no need to constantly check which thread was activated. You can change the signature of the Play()
method to accept an Object
, and you can pass the correct video to the method using that 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();
}
}
An even better approach is to encapsulate these three elements in a single object that contains a Video
object, a Thread
object, and a path string
.
If you own the Video
class, you might even want to make the Thread
and the string
values fields of that class.
You might even want to create a field on your buttons of type of this new object, so each button will be associated with a button.
This is much more typical of object oriented design. There is no reason you should maintain four separate identically sized arrays, each of different type.
Upvotes: 1
Reputation: 426
ThreadState is a bitmask-type property (enum has the [Flags] property, that's always the hint), so you don't check it directly using ==, you only need to check the relevant bit:
if ((t.ThreadState & ThreadState.Running) == ThreadState.Running) { ...
Read here about the meanings of the ThreadState values. From reading that and possibly the whole article, or whole book (highly recommended!) you'll also most likely notice that yours is probably not the ideal approach. Not knowing your exact endgame though, it;s hard to suggest an exact one.
Upvotes: 7