GrabCallback

GrabCallback.cs
using Itala;
using Itala.GenApi;

/// <summary>
/// "GrabCallback" is an extension of the simple Grab example which shows how to grab images
/// in an event-like fashion instead of using the native "polling" approach imposed by the IDevice
/// interface. The idea is to build the functionality over the IDevice.GetNextImage() function by
/// running it in a loop on a dedicated thread and passing each 
/// grabbed image to a callback function.
/// The synchronization logic is kept simple.
/// </summary>
internal class ImageMaster
{
  public void OnImage(IImage image)
  {
    Thread.Sleep(50);
    Console.WriteLine("\rImage with ID: " + image.FrameID + " processed.");
    image.Dispose();
  }
}

internal class Program
{
  private static void AcquisitionLoop(Action<IImage> userCallback, IDevice device, CancellationToken token)
  {
    while (!token.IsCancellationRequested)
    {
      IImage image = device.GetNextImage(500);
      userCallback(image);
    }
  }

  private static async Task GrabCallback_Sample()
  {
    Console.WriteLine("######## GrabCallback example started. ########");
    ISystem system = SystemFactory.Create();
    List<DeviceInfo> deviceInfos = system.EnumerateDevices();

    if (deviceInfos.Count == 0)
      throw new ItalaRuntimeException("No devices found. Example canceled.");
    if (deviceInfos[0].AccessStatus != DeviceAccessStatus.AvailableReadWrite)
      throw new ItalaRuntimeException("Target device is unaccessible in RW mode. Example canceled.");
    IDevice device = system.CreateDevice(deviceInfos[0]);
    Console.WriteLine("First device initialized.");

    device.StartAcquisition();
    Console.WriteLine("Acquisition started.");

    CancellationTokenSource cts = new CancellationTokenSource();
    CancellationToken token = cts.Token;

    Task task = Task.Run(() => AcquisitionLoop(new ImageMaster().OnImage, device, token));

    Console.ReadKey();
    cts.Cancel();
    await task;
    cts.Dispose();

    device.StopAcquisition();
    Console.WriteLine("Acquisition stopped.");
    device.Dispose();
    Console.WriteLine("Device instance disposed.");
    system.Dispose();
    Console.WriteLine("System instance disposed.");
  }

  private static async Task Main(string[] args)
  {
    try
    {
      await GrabCallback_Sample();
    }
    catch (Exception ex)
    {
      Console.WriteLine(ex.ToString());
    }
  }
}