0
我在C#應用程序中使用本機/非託管C++ DLL。我所說的本地函數來註冊使用的PInvoke在C#中的回調方法:用PInvoke回調非常慢
[DllImport("MyHook.dll", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.U1)] // necessary due to http://dotnet.dzone.com/articles/pinvoke-c-bool-return-values
private static extern bool InstallHook(CallbackPrototype callback);
private delegate int CallbackPrototype(byte* bytes, int size, int max);
// ...
var callback = new CallbackPrototype(MyCallback);
_callbackHandle = GCHandle.Alloc(callback);
var result = InstallHook(callback);
// somewhere when I'm removing the hook, I call _callbackHandle.Free();
然後,當事件發生時,本地C++ DLL調用我的回調。
private int MyCallback(byte* bytes, int size, int max)
{
//var buffer = new byte[size]; // A
//Marshal.Copy(new IntPtr(bytes), buffer, 0, size); // B
//WrapperInstance.ParseBytes(buffer, 0, size); // C
var x = 1 + 1; // D
return size;
}
當一切都被註釋掉,它運作良好。如果我在回調中開始取消註釋A行,它會變得很慢。我注意到了,因爲回調在關鍵時刻被調用。回調運行時間持續很長以至於我注意到它是人類是不可接受的。
這怎麼會發生? 大小參數僅從1到100.這就是最大隻需要分配100個字節 - 對於今天的計算機來說很少。我需要改進以使回調的運行時間快得多。有任何想法嗎?
爲了進一步測試,我添加了D行。這沒有任何影響。
編輯:對於更詳細的測試,我已經在類創建時分配了一個大緩衝區。所以A線不再處於回調狀態。如果B線被註釋掉,它會突然開始再次花費大量時間。這必須與託管代碼/虛擬機有關。我希望有可能讓它更快。
查看代碼正在通過*移除*來減慢*昂貴的方法調用當然是完全不直觀的。很明顯,您需要停止試錯法,並通過使用分析器來收集*證據*。 –
您的回調可能會被調用很多次? – ChaseMedallion
它被稱爲約。一次在兩秒鐘內。 Hans Passant,如果我正確地認識你,你會誤解某些東西。當我的UNcomment行A時,這個電話會變慢。對不起,如果我弄錯了,我的英文不是很好。當我注意到我眼中的性能問題時,我無法明白爲什麼我需要使用探查器。 –