怎样释放掉摄像头占用的资源
有一个Winform下的摄像头使用实例,摄像头被封装成了一个控件,但是当项目第一次运行时正常,以后再次运行就会弹出窗口,如下:
大侠们说是没有释放掉摄像头占用的资源,小弟不懂啊,请问各位大侠应该怎样释放资源?
实例主要代码如下:
namespace WebCamPictureBox
{
[Browsable(true), Description("WebCam PictureBox"), ToolboxBitmap(typeof(WebCamPictureBox), "WebPictureBox.jpg")]
public class WebCamPictureBox : PictureBox
{
#region API Declarations
[DllImport("user32", EntryPoint = "SendMessage")]
public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);
[DllImport("avicap32.dll", EntryPoint = "capCreateCaptureWindowA")]
public static extern int capCreateCaptureWindowA(string lpszWindowName, int dwStyle, int X, int Y, int nWidth, int nHeight, int hwndParent, int nID);
#endregion
#region API Constants
public const int WM_CAP_CONNECT = 1034;
public const int WM_CAP_DISCONNECT = 1035;
public const int WM_CAP_GET_FRAME = 1084;
public const int WM_CAP_COPY = 1054;
#endregion
#region Delegate
public delegate void WebCamConnectStateChangingEventHandler(object sender, EventArgs e);
public delegate void WebCamConnectStateChangedEventHandler(object sender, EventArgs e);
#endregion
#region Var
private int _CapHwnd;
private Timer _Timer = new Timer();
private bool _bIsStart;
private IDataObject _tempObj;
#endregion
#region Private Property
/// <summary>
/// Gets or sets a value indicating whether is started.
/// </summary>
/// <value><c>true</c> if is started; otherwise, <c>false</c>.</value>
public bool m_bIsStarted
{
get { return _bIsStart; }
set
{
if (_bIsStart != value){
OnWebCamConnectStateChanging(new EventArgs());
_bIsStart = value;
OnWebCamConnectStateChanged(new EventArgs());
}
}
}
#endregion
#region Control Properties
/// <summary>
/// The time intervale between frame captures
/// </summary>
[Browsable(true), Description("WebCam抓取間隔")]
public int CaptureInterval
{
get
{ return _Timer.Interval; }
set
{ _Timer.Interval = value; }
}
[Browsable(true), Description("是否已啟動WebCam")]
public bool IsStarted
{
get { return m_bIsStarted; }
}
#endregion
#region Event
public event WebCamConnectStateChangingEventHandler WebCamConnectStateChanging;
public event WebCamConnectStateChangedEventHandler WebCamConnectStateChanged;
#endregion
#region Constructer & Destructer
public WebCamPictureBox()
{
_Timer.Tick += new EventHandler(timer1_Tick);
_Timer.Interval = 100;
// setup a capture window
_CapHwnd = capCreateCaptureWindowA("WebCap", 0, 0, 0, this.Width, this.Height, this.Handle.ToInt32(), 0);
}
#endregion
#region Protected Method
/// <summary>
/// Raises the <see cref="E:WebCamConnectStateChanging"/> event.
/// </summary>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
protected void OnWebCamConnectStateChanging(EventArgs e)
{
if (WebCamConnectStateChanging != null)
WebCamConnectStateChanging(this, e);
}
/// <summary>
/// Raises the <see cref="E:WebCamConnectStateChanged"/> event.
/// </summary>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
protected void OnWebCamConnectStateChanged(EventArgs e)
{
if (WebCamConnectStateChanged != null)
WebCamConnectStateChanged(this, e);
}
#endregion
#region Public Method
/// <summary>
/// Tests the connect.
/// </summary>
/// <returns></returns>
public bool TestConnect()
{
try
{
SendMessage(_CapHwnd, WM_CAP_CONNECT, 0, 0);
SendMessage(_CapHwnd, WM_CAP_DISCONNECT, 0, 0);
return true;
}
catch (Exception e)
{
return false;
}
}
/// <summary>
/// Starts the video capture
/// </summary
public void Start()
{
try
{
// for safety, call stop, just in case we are already running
this.Stop();
m_bIsStarted = true;
// connect to the capture device
SendMessage(_CapHwnd, WM_CAP_CONNECT, 0, 0);
this._Timer.Start();
}
catch (Exception e)
{
MessageBox.Show("An error ocurred while starting the video capture. Check that your webcamera is connected properly and turned on.\r\n\n" + e.Message);
this.Stop();
}
}
/// <summary>
/// Stops the video capture
/// </summary>
public void Stop()
{
// stop the timer
m_bIsStarted = false;
this._Timer.Stop();
// disconnect from the video source
SendMessage(_CapHwnd, WM_CAP_DISCONNECT, 0, 0);
问题就在这里,请问怎样释放摄像头所占用的资源???
}
#endregion
}
[解决办法]
有没有例如close或者dispose之类的东西?
[解决办法]
找个头文件看看,再不行就退出的时候强制关闭程序能不能行?
Application.exit()
另外如果有线程的话 thread.IsBackground=true 自动退出线程
[解决办法]
http://blog.csdn.net/anya/archive/2009/07/22/4371256.aspx#1636480
[解决办法]
我也寻求中
[解决办法]
给点参考的资料啊。。。
[解决办法]
在.NET平台中内存管理由GC全负责,无需也不需开发者操心,而对于非托管资源GC就无能为力,这通常有两种参考的方案:Finalize和IDisposable模式,Finalze最大的问题就是执行的不确定性和对性能的阻塞,所以我们更推荐以IDisposable配合Finalized的方式来实现对非托管资源的管理工作。
在.NET中,简单的说IDisposable模式就是在自定义类中实现IDisposable接口,在其中定义的Dispose方法中释放非托管资源。那么对于您的问题就有了对应的思路:
Q1:是不是只有存在非托管资源的情况下才有必要实现Dispose接口?
Q2:在实现Dispose接口的时候,释放托管资源的代码段应该写什么?
Q3:托管资源本来就由GC来处理,我想在实现Dispose接口的时候,无需手动写释放托管资源的代码吧?
A1:这是显然的,在.NET框架类库中实现IDisposable接口的基本是持有非托管资源的类型,例如IDbConnection、Font、Brush、Steam、TextReader等等,从名字就可以看出端倪;
A2:应该怎么写,取决于你释放的非托管资源是什么,一般来说就是调用Win API完成资源清理,例如对于数据库资源资源你通常:
if (disposing)
{
if (connection != null)
connection.Dispose();
}
而对于文件资源,你可能
if (fileHandle != IntPtr.Zero)
{
CloseHandle(fileHandle);
fileHandle = IntPtr.Zero;
}
A3:记住,永远避免自行处理托管资源。
[解决办法]
端口 close 有过没