I need to make a console application that uses Kinect, with Kinect SDK and c#. Since it's a console application, I've found polling to be the best way to retrieve the frames I need to process. I'll need to retrieve frames from the depth camera and the rgb camera, do some processing on then in separate threads (one for the depth image and one for the rgb image), and give an output to the user for each of the two processed frames. The way I've been thinking about doing this is the following:
1 - create 2 threads, the first is on the method that polls the rgb camera and do the processing, the second is on the method that polls the depth camera and do the processing
2 - Start the threads
3 - enter a while some stop condition loop
4 - check separately if each thread is alive, if not, create them again and start them again
I've made a test program that follows those steps and it works, but I'm not sure it's the best way of doing it. My test program is
class Program
{
private static ClassExecutioner Executioner;
private static Class1 Cls;
static void Main(string[] args)
{
Executioner = new ClassExecutioner();
Cls = new Class1();
Thread fThread = new Thread(new ThreadStart(processA));
Thread sThread = new Thread(new ThreadStart(processB));
fThread.Start();
sThread.Start();
while (true)
{
if (!fThread.IsAlive)
{
fThread = new Thread(new ThreadStart(processA));
fThread.Start();
}
if (!sThread.IsAlive)
{
sThread = new Thread(new ThreadStart(processB));
sThread.Start();
}
}
}
static void processA()
{
String frameA = Cls.pollA();
Executioner.CallA(frameA);
}
static void processB()
{
String frameB = Cls.pollB();
Executioner.CallB(frameB);
}
}
Class 1 methods represent the polling of the cameras on kinect
class Class1
{
private int a;
private int b;
public Class1()
{
a = 0;
b = 0;
}
public String pollA()
{
String frame = "this is " + a % 100;
a++;
return frame;
}
public String pollB()
{
String frame = "I am " + b % 100;
b++;
return frame;
}
}
Executioner represents the methods that process the frames obtained from Kinect
class ClassExecutioner
{
public ClassExecutioner()
{
}
public void CallA(String frameA)
{
Random rand = new Random();
int time = rand.Next() % 1000000000;
//'processing' - wait some time
for (int i = 0; i < time; i++)
{
}
// finishes the processing of the 'frame' from stream A
Console.WriteLine(frameA);
}
public void CallB(String frameB)
{
Random rand = new Random();
int time = rand.Next() % 1000000000;
// 'processing' - wait some time
for (int i = 0; i < time; i++)
{
}
// finishes the processing of the 'frame' from stream B
Console.WriteLine(frameB);
}
}
The program is very simple but ilustrates well what I want to do with the Kinect streams. The problem is, I'm not sure this is the best way of doing it or even if this is gonna work at all on a practical, Kinect application. Keep in mind that, for now, each processing (depth and rgb) doesn't need information from the other.
Thanks in advance!
It might be cool to look into the ReactiveExtensions framework. It deals with async event streams very cleanly.
You can write LINQ against the data sources and do very interesting composable operations.
http://msdn.microsoft.com/en-us/data/gg577609.aspx
You basically would have two IEnumerable sequences (the things that loop infinitely) that yield out the frame at the given interval. You can then "query" these sequences using Rx. RX handles all the complicated threading issues for you and makes your consumer code clean and simple.
To be clear, you don't want to be creating new threads each time. You can create two infinite enumerables that each run on their own thread and yield out the result on each iteration. That way they don't even "die"
Related
I'm very new to c# and coding in general and am having some problems implementing a timer in a for loop. Basically, the bit of code below is trying to create a number representative of trash output by an island at set intervals, with each output weighted based on island population to be a bit less predictable. it then adds the generated trash figure to a total. The problem I'm having is that the way tutorials use the Timer class means creating an 'Intervaltimer_Elapsed(object sender, ElapsedEventArgs e)' function outside of Main() and I can't work out how to then add whatever is generated by this back to the weights[] array in the Main(). All I really want to do is as soon as the compiler goes into the for loop, tell it to wait 'x' ticks, then continue. Thread.Sleep isn't an option because this is to go in unity, so would interrupt other things. apologies if the code below is a bit gory!
{
class Program
{
public static double trashperstan8 = 600 * 3.21;
public static int population = 1000;
public static double trashperpersperday = 1;
public static double interval = 60;
public static double intperday = 1440 / interval;
public static double trashperint = population * trashperpersperday * (interval / 1440);
public static int weightnum = population / 200;
static void Main(string[] args)
{
double Trashlevel = new double();
double stand8sfilled = new double();
Timer intervaltimer = new Timer((interval / 30) * 1000);
Console.WriteLine(weightnum);
for (int inti = 0; inti < intperday; inti++)
{
/* at this point, I want to basically tell the code: each time you go
through the for loop, wait for x number of ticks then do the method */
Console.WriteLine(inti);
double[] weights = new double[weightnum];
Random rand = new Random();
for (int i = 0; i < weightnum; i++)
{
double weightcontrib = rand.NextDouble();
weights[i] = weightcontrib;
Console.WriteLine("{0}: {1}", Array.IndexOf(weights, weightcontrib), weightcontrib);
}
double finalweight = 2 * (weights.Sum() / weightnum);
Console.WriteLine("final weight " + finalweight);
double weightedtpi = trashperint * finalweight;
Trashlevel = Trashlevel + weightedtpi;
stand8sfilled = stand8sfilled + (weightedtpi / trashperstan8);
}
Console.WriteLine("trash level " + Trashlevel);
Console.WriteLine("stand8s filled " + stand8sfilled);
}
private static void Intervaltimer_Elapsed(object sender, ElapsedEventArgs e)
{
}
}
}
All I really want to do is as soon as the compiler goes into the for loop, tell it to wait 'x' ticks, then continue. Thread.Sleep isn't an option because this is to go in unity, so would interrupt other things.
Solution 1: Don't write a loop at all. The timer already is logically a loop.
Write a method that is the "body" of the "loop".
"Starting the loop" is activating a timer where the body method is the event handler and the timer fires every n milliseconds
"Terminating the loop" is deactivating the timer.
Solution 2: Write a loop, don't use a timer.
Make the method async and then await Task.Delay(whatever); to asynchronously wait for your delay. Your method will suspend when it hits the await, and resume at some point after the delay task is complete.
The latter is probably the better solution in that the code more closely resembles your description of it.
I don't know enough about Unity to say which is the better solution in their framework.
I'm creating a console game as simple as "I generate a random number, find it", but with many options.
My current code (without what I want here) is availlable on GitHub: https://github.com/crakmaniaque/trouvezmoi
What I want is to create a version of my game which will be timed, so the computer generates numbers, the user finds it, it generates a new one and the player have 90 seconds to find a max lot of random numbers. I can code this easily.
What I will need help is to stop the game (a thread) after 90 seconds and retrieve the number of answers founded from the thread. The Console.Title should also show time remaining. The attempt I've tried works, but the thread is not interrupted if console is asking for number input (Console.ReadLine()). But the timer is for the entire process, not only user input.
private static void timerb()
{
int t = 90;
for (int i = 0; i < 90; i++)
{
Console.Title = t + " seconds remaining";
Thread.Sleep(1000);
t--;
}
}
private static void cGame()
{
Thread t = new Thread(timerb);
t.Start();
while (t.IsAlive)
{
bool good = false;
int rnd = new Random().Next(0,10); // 0 and 10 are sample
while (!good)
{
try
{
Console.Write("Enter a number between x and y >");
int i = int.Parse(Console.ReadLine());
if (i == rnd)
{
good = true;
}
}
catch (FormatException)
{
Console.WriteLine("Invalid answer.");
}
}
}
}
I don't know much about threading and at that point I'm stuck.
Can someone help me with my problem? I'm using .NET 2.0.
Perhaps you are looking for a timer? You could register an event, that would fire after 90 seconds, that would run while the loop is happening. The documentation can be found here: Timer class MSDN documentation.
I believe the usage would be:
Timer timer = new Timer { Interval = new Timespan (0,1,30);
timer.elapsed += //function to fire to kill the app or the game
You'd need to make each console read with a timeout equal to the amount of time left in the game. That solves that issue.
Then, you need a way to signal the timerb thread to shut down when the main game loop has ended. I think the simplest way would be to end the game loop when the remaining time is <= zero. Alternatively, you could make timerb singnal the main thread to shut down when t == 0. Inter-thread communication is always complicated and error-prone, though.
You can signal the timerb thread to shut down by setting a volatile bool shutdown to true and by making timerb poll that variable and shut itself down.
I have this code, and have a function named STARTWORK(int THREADNR) which cannot be called by 2 threads. Basically all the work of my program is contained in this function, where in the WORKVOID1() and WORKVOID2() i use separate for() functions to run through the data, and the for() function is split in half so that the 2 functions cover half-half of the data to be much faster and work on multicore processor.The problem is that if there is only the main thread, it works like a charm, but if i try to split the STARTWORK() into 2 parts in WORKVOID1() and WORKVOID2() each in multiple threads it doesn't work, so please help me fix it.
public void OPTIMIZATION_ITERATION()
{
Thread WORK = new Thread(WORKVOID);
WORK.Name = "T1";
WORK.Start();
Thread WORK2 = new Thread(WORKVOID2);
WORK2.Name = "T2";
WORK2.Start();
}
public void WORKVOID()
{
for (ALPHA = 0.001; ALPHA <= 0.5; ALPHA += 0.001)
STARTWORK(1);
}
public void WORKVOID2()
{
for (ALPHA = 0.5; ALPHA <= 1; ALPHA += 0.001)
STARTWORK(2);
}
public void STARTWORK(int THREAD)
{
//.......bunch of calculations then it writes it to file
System.IO.StreamWriter WRITE = new System.IO.StreamWriter("OUTPUT_T"+THREAD+".txt", true);
WRITE.BaseStream.Seek(0, SeekOrigin.End);
WRITE.WriteLine(/*..calculations are written to file..*/);
WRITE.Close();
WRITE.Dispose();
}
The STARTWORK(int THREADNR) contains a parameter which will assign a number that will write the data to file so that the 2 will have different filenames, while ALPHA is a global double variable.
if your working in c# you might want to try this.
public void OPTIMIZATION_ITERATION()
{
Thread WORK = new Thread(new ThreadStart(WORKVOID));
WORK.Name = "T1";
WORK.Start();
Thread WORK2 = new Thread(new ThreadStart(WORKVOID2));
WORK2.Name = "T2";
WORK2.Start();
}
public void WORKVOID()
{
for (ALPHA = 0.001; ALPHA <= 0.5; ALPHA += 0.001)
STARTWORK(1);
}
public void WORKVOID2()
{
for (ALPHA = 0.5; ALPHA <= 1; ALPHA += 0.001)
STARTWORK(2);
}
I think the problem is ALPHA. As soon as you start the second thread you set it equal to the condition that the first thread is looking for (ALPHA <= .5), then the first thread increments ALPHA by .001. The net result is that the first thread is highly unlikely to write anything to the file (maybe one line, depending on timing).
Beyond that, I don't really see the point of trying to to do this in parallel, if you are writing to the same disk, it's not going to help anything. If the calculations you are doing are CPU intense, then it might be a better approach to make the calculations parallel and then write everything to disk after it's done, or in chunks if memory is an issue.
Global variables such as ALPHA cannot be used safely in multi-threaded contexts. This is because both threads are allowed to read/write at the exact same time which causes a race condition. I recommend you change your work methods to accept a double parameter. That way, each method would be using a local variable instead of a global shared variable.
I have some code which is its simplest form does the following.
float result = RunSimulation();
totalResult += result;
If I run this in a single thread I get different results compared to running it in multiple threads. If I put a lock around the totalResult addition then I get the same result but at a massive performance cost.
With floats being 32 bit I thought that operations on them were guaranteed to be atomic, so I don't understand why threading this is giving me different results.
I can just use ThreadStatic fields to keep count of to totals and then add them together with locks when the threads terminate, so it's not a solution that I'm looking for, just an explanation.
I wrote some test code to check this in it's simplest form. This code is as follows and also produces different results for every run.
class Program
{
static float total;
static int threadCount;
static void Main(string[] args)
{
while (true)
{
total = 0;
for (int i = 0; i < 10; i++)
new Thread(ThreadMethod).Start();
do
{
Thread.Sleep(10);
} while (threadCount > 0);
Console.WriteLine(total);
if (Console.ReadKey(true).Key == ConsoleKey.Escape)
break;
}
}
static void ThreadMethod()
{
threadCount++;
for (int i = 0; i < 100000; i++)
total = total + 1.234f;
threadCount--;
}
}
Reading and writing floats is atomic, this is guaranteed by the language. However, operations on floats are not atomic. There is no way around using some kind of syncing in this case.
On a sidenote, you have a small race condition, the while might exit before any thread was ever started.
I know of course that I can not draw onto the same Graphics object from different threads, but is it also true that I can not draw to different Graphics objects in different threads?
Consider the following console program:
class Program
{
static ThreadDrawer[] drawers;
static void Main(string[] args)
{
int numThreads = 8;
drawers = new ThreadDrawer[numThreads];
for (int i = 0; i < numThreads; i++)
{
drawers[i] = new ThreadDrawer();
drawers[i].Start();
}
for (int i = 0; i < numThreads; i++)
{
drawers[i].Wait();
}
Console.WriteLine("Complete.");
Console.ReadKey();
}
class ThreadDrawer
{
private Thread thread;
private AutoResetEvent resetEvent;
public ThreadDrawer()
{
thread = new Thread(DrawRandomCircles);
resetEvent = new AutoResetEvent(false);
}
public void Start()
{
thread.Start();
}
public void Wait()
{
resetEvent.WaitOne();
}
public void DrawRandomCircles()
{
Random r = new Random(Environment.TickCount);
using (Bitmap b = new Bitmap(1000, 1000))
using (Graphics g = Graphics.FromImage(b))
{
for (int i = 0; i < 100000; i++)
{
g.DrawEllipse(Pens.Red, new Rectangle(r.Next(1000), r.Next(1000), 200, 200));
}
}
resetEvent.Set();
}
}
}
The program creates a Bitmap in each thread and proceeds to draw random ellipses on it using a Graphics object, also generated per thread from the Bitmap.
Due to a requirement to build for .net2 the multithreading is implemented using Threads and AutoResetEvents instead of TPL.
The program executes without throwing an exception, but it executes serially. Using n threads multiplies execution time by n and it is clear to see using the task manager that only one core is being used.
Important to take note that none of this is tied to any UI element.
What is going on here? Is the Graphics object locking on a static object?
Here's a screen-shot of the concurrency analyzer I used to see what's going on with these threads:
Yes, you can see lots of red (blocking) with flecks of green (execution). The threads are taking turns entering a critical section that's acquired inside the internal GpGraphics::RenderDrawPath() function. The larger blobs of green is where the program actually drew the lines (I replaced DrawEllipse with DrawRectangle and got rid of the Random call).
There is some concurrency, you can for example see the RenderDrawPath() call being overlapped by the code that renders the anti-aliased lines, overall cpu load is around 35%. But there isn't much of it.
Nothing you can do about it of course. You get ahead by overlapping the logic in your own program to decide what to draw with the GDI+ calls. Which will normally happen, the test is too synthetic.
It seems like locking happens in unmanaged code, inside GDI+ library (unfortunately, this behavior is not mentioned in official docs).
Similar question: Parallelizing GDI+ Image Resizing .net
I'm not 100% sure.. but yes, there is a private static locking object in the Graphics class. It appears to be locked only from GetHalftonePalette, which in turn, is called whenever a Bitmap is initialized within the Graphics object. It would appear that this could be the cause of contention.
(Note: Initial findings after 5 minutes of using ILSpy.. not very in-depth)