我在尝试构建一个窗口时遇到了问题,我可以在其中显示来自我的microsoft lifecam的Feed。基本上我可以拍摄一个或多个屏幕截图,但如果我把代码放在一个线程中(这样我就可以实时显示feed而不会阻止ui)API失败,告诉我没有设备找到。这是代码:
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 :(得分:0)
让编译器为您管理任务。完全摆脱匿名委托,只需将循环放在事件处理程序中,并使用await Task.Delay
代替Thread.Sleep