2017-02-17 19 views
0

У меня возникла проблема при попытке создать окно, в котором я могу показать фид из моей жизненной схемы microsoft. В принципе, я могу взять один или несколько скриншотов, но если я поместил код внутри потока (чтобы я мог показывать канал в реальном времени, не блокируя ui), API не работает, сообщая мне, что никаких устройств, где они найдены. Вот код:Microsoft LifeCam ESCAPI - работает в uad thead, а не внутри задачи

C++ CLI:

EasyPicture::EasyPicture() 
{ 
    int devices = setupESCAPI(); //returns 1 if run synchronously, 0 otherwise 
    _apiInitialized = devices > 0; 
    std::cout << (_apiInitialized ? "Escapi initialized successfully!\n" : "Failed to init escapi.\n"); 
    _capture = new struct SimpleCapParams(); 
} 

bool EasyPicture::GetFrame(void* buffer, int width, int height) 
{ 
    if (!_apiInitialized || buffer == nullptr || width == 0 || height == 0) 
     return false; 
    pin_ptr<int> buffPtr = reinterpret_cast<int*>(buffer); 

    _capture->mTargetBuf = buffPtr; 

    _captureInitialized = _capture->mWidth == width && _capture->mHeight == height; 

    _capture->mWidth = width; 
    _capture->mHeight = height; 

    if (!_captureInitialized) 
    { 
     //works if run synchronously, otherwise returns 0 (failed) 
     if (initCapture(0, _capture) == 0) //Maybe the device is already in use 
     { 
      if (Disconnect()) // try to disconnect it 
      { 
       if (initCapture(0, _capture) == 0) 
       { 
        _captureInitialized = false; 
        return false; 
       } 
       _captureInitialized = true; 
      } 
      else 
      { 
       _captureInitialized = false; 
       return false; 
      }    
     } 
    } 

    doCapture(0); 

    while (isCaptureDone(0) == 0) 
    { 
     /* Wait until capture is done. */ 
    } 

    return true; 
} 

C# код

private void UserControl_Loaded(object sender, RoutedEventArgs e) 
    { 
     _cts = new CancellationTokenSource(); 
     _frameLoop = new Task(() => 
     { 
      Frame = new Bitmap(_width, _height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); 
      var BoundsRect = new System.Drawing.Rectangle(0, 0, _width, _height); 
      BitmapData bmpData = Frame.LockBits(BoundsRect, ImageLockMode.WriteOnly, Frame.PixelFormat); 
      int counter = 0; 
      while(!_cts.IsCancellationRequested) 
      { 
       unsafe 
       { 
        if (!_picHelper.GetFrame((void*)bmpData.Scan0, _width, _height)) 
        { 

        } 
        else 
        { 
         Frame.Save("Test_" + counter + ".bmp"); //For now i just save the frame, i have yet to figure out how to put the bitmap in xaml without copying it... 
         /* Image = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
          Frame.GetHbitmap(), 
          IntPtr.Zero, 
          System.Windows.Int32Rect.Empty, 
          BitmapSizeOptions.FromWidthAndHeight(_width, _height));*/ 
        } 
       } 
       Thread.Sleep(500); 
      } 
      Frame.UnlockBits(bmpData); 
     },_cts.Token); 
     _frameLoop.RunSynchronously();// Start(); Works only with RunSynchronously, but blocks ui of course 
    } 

Может кто-то мне точку в правильном направлении?

ответ

0

Позвольте компилятору управлять заданием для вас. Избавьтесь от анонимного делегата, просто поместите цикл в обработчик события и используйте await Task.Delay вместо Thread.Sleep