Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I would like to use a timer in my C# program with millisecond accuracy to keep a camera in sync with some events and keep shooting a picture every 250ms (or 1/4 sec, or I might adjust it to even shorter times like 200ms or 100ms). The normal timer event can be used for this.

But I wonder what would be the best way to do this.

Also I think I should NOT write the whole capture routine in it, but instead just raise another thread (multi-threading) to process the image with some vision logic on it, as my vision logic takes about 1 seconds, so I will get some queue here.

If my vision algorithms would take 1 seconds per thread, would this mean that on a multicore (12 cores) PC that such code thread would go to the next available free processor or am I thinking to easily about multitasking?

share|improve this question
3  
isn't this question rather for Stack-Overflow ? –  Stephane Rolland Jan 13 '13 at 16:06
    
Are you looking for a conceptual answer or a code answer? –  Walter Jan 13 '13 at 18:20
add comment

2 Answers

I want to add another point to Danny Varod's already good answer, focusing on the question in your last paragraph.

Assuming you're handling the events raised by the multimedia timer or another high-resolution timer, you now need to dispatch your heavy processing task in another thread. .NET's libraries make this relatively easy using the Task Parallelism Library (TPL) if you're using .NET 4.0, or directly using the ThreadPool for earlier versions.

Let's say you have this (very sketchy) code:

private void ProcessImage(object imageToProcess)
{
    // Do whatever. Process the image, save the results, etc.
    // This is the 1-sec process.
}

private void myTimer_Elapsed()
{
    Image capturedImage = myCamera.CaptureImage(); // or whatever.
    Task.Factory.StartNew(ProcessImage, capturedImage);
}

This starts a new Task (a wrapper around an asynchronous method) that is launched on a ThreadPool thread. If your machine has multiple CPUs and multiple cores, the ThreadPool will have a lot of available threads, and will process many of these requests in parallel. Hopefully, this will allow the processing tasks to keep up with the image capture tasks. You might have to read up on the threadpool and see how to tweak the available threads for machines with lots of CPUs, but the worst case scenario is that the processing tasks get backlogged, but the threadpool (which is at the heart of the Tasks library) will just queue them up and get to them eventually.

Note, though, that you are not guaranteed that the tasks will be executed in the order they are captured.

If you're using an older version of C#, replace the call to Task.Factory.StartNew with calls to ThreadPool.QueueUserWorkItem, which in this case (where we're not using continuations and aggregated error handling) will be practically identical in usage.

share|improve this answer
    
Excellent!, the order of images is of less importance, its more about detecting futures, and logging them. –  user613326 Jan 13 '13 at 23:42
add comment
  1. Use the Multimedia Timer. It works well with even 10mS intervals (and perhaps less).

  2. When the timer event occures, you may have to dispatch to the main thread (or another single thread), depending on whether or not your camera API and image processing API support access from multiple threads. Use the Dispatcher class for this.

  3. Make sure your event handler is shorter than the timer interval, when the timer event occurs, check if the event handler is busy and if so decide what to do (e.g. ignore event).

  4. Decide what to do with the images, either create a new image at each event (not recommended due to GC cost), or reuse image buffer so long as the image size and color depth hasn't changed. You may want to create an output image for each stage of your image processing, to enable pipe-lining the image processing and enable the image processing to modifying image size/color depth. If your image processing API supports multi-threading, then you will need to make sure you are not using the same image buffer simultaneously (e.g. using pipe-line synchronization or using different images for each event).

Edit: If your processing takes ~1Sec, then you will end up with a growing queue of images (or amount of threads) because you won't be able to keep up. If you can't wait a long time for the processing to end after the capturing does, you will need to refactor the image processing code. Try moving it to the GPU (using GPGPU).

share|improve this answer
    
Well GPU programming is beyond my level currently. I have read some material too about multimedia timer, but your link was new.. Isnt the standard .net timer good enough ? (the one that can be dropped on a form) for the 200 miliseconds delay; i wonder what the difference would be, perhaps you know what the differences are ? > oh forgot to mention not all images would take 1 sec most of them will go faster, but i was curious what would happen if a multi-thread could run twice are not at around the same time. –  user613326 Jan 13 '13 at 23:39
    
If the processing library doesn't use any graphics resources (screen, graphics card) and doesn't have any static state, then you probably can use it via multiple threads/tasks. For this .NET 4.0 tasks if a good solution (as Avner wrote). If the order of completion of tasks doesn't matter and the time it take doesn't matter, then you can just store the results using any thread safe approach (e.g. store as independent entries into a DB or as independent files to disk). –  Danny Varod Jan 14 '13 at 14:47
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.