2010-04-02 78 views
1

我正試圖編寫一個應用程序,從計算機上的默認音頻錄製設備獲取聲音。當運行從我的託管代碼訪問DirectX的任何代碼,我得到這個錯誤:LoaderLock被檢測到,並關閉警告沒有幫助

DLL 'C:\Windows\assembly\GAC\Microsoft.DirectX.DirectSound\1.0.2902.0__31bf3856ad364e35\Microsoft.DirectX.DirectSound.dll' is attempting managed execution inside OS Loader lock. Do not attempt to run managed code inside a DllMain or image initialization function since doing so can cause the application to hang.

DevicesCollection coll = new DevicesCollection(); 

Device d = new Device(DSoundHelper.DefaultCaptureDevice); 

Capture c = new Capture(DSoundHelper.DefaultCaptureDevice); 

都會導致LoaderLock MDA彈出並告訴我有一個問題。爲了解決這個問題,我搜索了互聯網(包括stackoverflow),但大多數人只是說要關閉警告,這是行不通的。當我關閉警告時,拋出了一個通用的ApplicationException,這更加有用。我也看到了this question的答案,這並沒有幫助,因爲他說刪除導致錯誤的代碼。其他人則表示「修復你的代碼」。

我的問題是:

我怎麼能叫從C#任何(最好是管理)的DirectX代碼沒有得到這個錯誤?

編輯:這是堆棧跟蹤我得到:

at Microsoft.DirectX.DirectSound.Device..ctor(Guid guidDev) 
at Autotuner.fMain.button1_Click(Object sender, EventArgs e) in C:\\Users\\Scott\\Documents\\Visual Studio 2008\\Projects\\Autotuner\\Autotuner\\Form1.cs:line 17 
at System.Windows.Forms.Control.OnClick(EventArgs e) 
at System.Windows.Forms.Button.OnClick(EventArgs e) 
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) 
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) 
at System.Windows.Forms.Control.WndProc(Message& m) 
at System.Windows.Forms.ButtonBase.WndProc(Message& m) 
at System.Windows.Forms.Button.WndProc(Message& m) 
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) 
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) 
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) 
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData) 
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) 
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) 
at System.Windows.Forms.Application.Run(Form mainForm) 
at Autotuner.Program.Main() in C:\\Users\\Scott\\Documents\\Visual Studio 2008\\Projects\\Autotuner\\Autotuner\\Program.cs:line 18 
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args) 
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
at System.Threading.ThreadHelper.ThreadStart() 
+0

拋出什麼異常? – SLaks 2010-04-02 15:42:40

+0

一個例外很好,發佈StackTrace。 – 2010-04-02 17:01:41

+1

其字面上稱爲ApplicationException的消息「應用程序中出現錯誤」 – 2010-04-02 18:12:30

回答

2

託管環境之外,C++中的加載程序鎖內執行代碼的最簡單的方法之一就是具有嵌入式DLL中的表演類的在全局範圍初始化。

執行dll對象初始化的唯一時間是來自操作系統的DllMain消息 - 但在這些消息中加載器鎖定處於活動狀態。加載器鎖可以防止不同線程加載dll同時進入單個dll的DllMain。

要解決這個問題在C++(以及可能的託管環境)中很困難,因爲在dll中可能有很多隱式對象需要構建。儘管如此,你需要找到從DllMain調用的初始化代碼,並確保從顯式初始化/關閉函數中調用dllMain導出或準時完成的初始化代碼。