I keep getting this error after my code runs between 5-10 min.
CallbackOnCollectedDelegate detected Message: The callback was made to the garbage collector received from the type "CashRecyclerTestapp! MessageMonitor + NativeMethods + WndProc :: Invoke". This can lead to application crashes, crashes, and data loss. When delegates are delegated to unmanaged code, they must remain alive by the managed application until it is guaranteed that they will never be called.
I am writing an application for a vending machine and I have a dll that sends messages that I need to catch in my application
this is my code, I received the source code from the Internet to catch messages and here it continues to receive an error.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security;
using System.Threading;
public delegate void MessageMonitorEventHandler(IntPtr hwnd, int message, IntPtr wParam, IntPtr lParam);
public static class MessageMonitor
{
public static IntPtr WindowHandle
{
get
{
EnsureMonitorWindowCreated();
return monitorWindowHandle;
}
}
public static void WatchMessage(int message)
{
EnsureMonitorWindowCreated();
messageSetLock.AcquireWriterLock(Timeout.Infinite);
try
{
messageSet[message] = message;
}
finally
{
messageSetLock.ReleaseWriterLock();
}
}
public static event MessageMonitorEventHandler MessageReceived;
private static object syncObject = new object();
private static SynchronizationContext syncContext;
private static IntPtr monitorWindowHandle = IntPtr.Zero;
private static ReaderWriterLock messageSetLock;
private static Dictionary<int, int> messageSet;
private static void EnsureMonitorWindowCreated()
{
lock (syncObject)
{
if (messageSetLock == null)
messageSetLock = new ReaderWriterLock();
if (messageSet == null)
messageSet = new Dictionary<int, int>();
if (syncContext == null)
syncContext = AsyncOperationManager.SynchronizationContext;
if (monitorWindowHandle == IntPtr.Zero)
{
int lastWin32Error = 0;
using (ManualResetEvent threadCreateSignal = new ManualResetEvent(false))
{
Thread thread = new Thread((ThreadStart)delegate
{
if ((monitorWindowHandle = CreateWindow()) == IntPtr.Zero)
lastWin32Error = Marshal.GetLastWin32Error();
threadCreateSignal.Set();
if (monitorWindowHandle != IntPtr.Zero)
{
NativeMethods.MSG msg = new NativeMethods.MSG();
while (UnsafeNativeMethods.GetMessage(ref msg, IntPtr.Zero, 0, 0))
UnsafeNativeMethods.DispatchMessage(ref msg);
}
});
thread.Name = "MessageMonitorThread";
thread.IsBackground = true;
thread.Start();
threadCreateSignal.WaitOne();
}
if (lastWin32Error != 0)
throw new Win32Exception(lastWin32Error);
}
}
}
private static IntPtr CreateWindow()
{
IntPtr hWnd = IntPtr.Zero;
string className = RegisterWndClass();
if (className != null)
return UnsafeNativeMethods.CreateWindowEx(0, className, className, 0, 0, 0, 0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, null);
return hWnd;
}
private static string RegisterWndClass()
{
NativeMethods.WNDCLASS wc = new NativeMethods.WNDCLASS();
wc.lpfnWndProc = WndProc;
for (int n = 1; n < int.MaxValue; n++)
{
wc.lpszClassName = String.Format(CultureInfo.InvariantCulture, "MessageMonitorWindow:{0}", n);
short ret = UnsafeNativeMethods.RegisterClass(wc);
if (ret != 0)
return wc.lpszClassName;
else if (Marshal.GetLastWin32Error() != NativeMethods.ERROR_CLASS_ALREADY_EXISTS)
return null;
}
return null;
}
public static IntPtr WndProc(IntPtr hwnd, int message, IntPtr wParam, IntPtr lParam)
{
messageSetLock.AcquireReaderLock(Timeout.Infinite);
bool watchingThisMessage = messageSet.ContainsKey(message);
messageSetLock.ReleaseReaderLock();
if (watchingThisMessage)
{
NativeMethods.MSG msg = new NativeMethods.MSG();
msg.hwnd = hwnd;
msg.message = message;
msg.wParam = wParam;
msg.lParam = lParam;
syncContext.Post(delegate(object state)
{
MessageMonitorEventHandler handler = MessageReceived;
if (handler != null)
{
NativeMethods.MSG msgCopy = (NativeMethods.MSG)state;
handler(msgCopy.hwnd, msgCopy.message, msgCopy.wParam, msgCopy.lParam);
}
}, msg);
}
return UnsafeNativeMethods.DefWindowProc(hwnd, message, wParam, lParam);
}
#region PInvoke
private static class NativeMethods
{
public const int ERROR_CLASS_ALREADY_EXISTS = 0x582;
public delegate IntPtr WndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class WNDCLASS
{
public int style;
public WndProc lpfnWndProc;
public int cbClsExtra;
public int cbWndExtra;
public IntPtr hInstance = IntPtr.Zero;
public IntPtr hIcon = IntPtr.Zero;
public IntPtr hCursor = IntPtr.Zero;
public IntPtr hbrBackground = IntPtr.Zero;
public string lpszMenuName;
public string lpszClassName;
}
[Serializable, StructLayout(LayoutKind.Sequential)]
public struct MSG
{
public IntPtr hwnd;
public int message;
public IntPtr wParam;
public IntPtr lParam;
public int time;
public int pt_x;
public int pt_y;
}
}
[SuppressUnmanagedCodeSecurity]
private static class UnsafeNativeMethods
{
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr CreateWindowEx(int dwExStyle, string lpszClassName, string lpszWindowName, int style, int x, int y, int width, int height, IntPtr hWndParent, IntPtr hMenu, IntPtr hInst, [MarshalAs(UnmanagedType.AsAny)] object pvParam);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr DefWindowProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr DispatchMessage([In] ref NativeMethods.MSG msg);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetMessage([In, Out] ref NativeMethods.MSG msg, IntPtr hWnd, int uMsgFilterMin, int uMsgFilterMax);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern short RegisterClass(NativeMethods.WNDCLASS wc);
}
#endregion
}
,
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
[DllImport("PaymentManager.dll")]
static extern int openpaymentmanager();
[DllImport("PaymentManager.dll")]
static extern int closepaymentmanager();
[DllImport("PaymentManager.dll")]
static extern int startpaymentmanager(IntPtr handle,int messageaddress,int devices,int protocol,int messageconfig);
[DllImport("PaymentManager.dll")]
static extern int stoppaymentmanager();
[DllImport("PaymentManager.dll")]
static extern int setpaymentmanager(int command, int selection, int info1, int info2);
private void Form1_Load(object sender, EventArgs e)
{
int closepaymentmng = closepaymentmanager();
const int WM_USER = 0x0400;
MessageMonitor.MessageReceived += new MessageMonitorEventHandler(MessageMonitor_MessageReceived);
MessageMonitor.WatchMessage(0x3B9);
int openpaymentmng = openpaymentmanager();
int startpaymentmnh = startpaymentmanager(MessageMonitor.WindowHandle , 0x3B9, 0, 0, 0);
long setpaymentmng = setpaymentmanager(0, 0, 0, 0);
textBoxprice.Text = "0";
textBoxpaid.Text = "0";
}
private void MessageMonitor_MessageReceived(IntPtr hwnd, int message, IntPtr wParam, IntPtr lParam)
{
Console.WriteLine(string.Format ("message:{0} , wparam= {1} ,lparam = {2}", message,wParam,lParam));
if (wParam.ToString() == "17")
{
textBoxpaid.Text = (Convert.ToDecimal( textBoxpaid.Text)+ Convert.ToDecimal( lParam.ToString())/100).ToString();
}
if (wParam.ToString() == "18")
{
textBoxpaid.Text = (Convert.ToDecimal(textBoxpaid.Text) + Convert.ToDecimal(lParam.ToString()) / 100).ToString();
}
if (wParam.ToString() == "33")
{
textBoxpaid.Text = (Convert.ToDecimal(textBoxpaid.Text) - Convert.ToDecimal(lParam.ToString()) / 100).ToString();
}
}
ect.....
,
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private const string crashDllName = @"C:\Users\Chantelle\Documents\CashRecyclerTestapp\CashRecyclerTestapp\bin\Debug\PaymentManager.dll";
[DllImport(crashDllName)]
static extern int openpaymentmanager();
[DllImport(crashDllName)]
static extern int closepaymentmanager();
[DllImport(crashDllName)]
static extern int startpaymentmanager(IntPtr handle,int messageaddress,int devices,int protocol,int messageconfig);
[DllImport(crashDllName)]
static extern int stoppaymentmanager();
[DllImport(crashDllName)]
static extern int setpaymentmanager(int command, int selection, int info1, int info2);
private static IntPtr hndle;
private static MessageMonitorEventHandler msgmntr;
private void Form1_Load(object sender, EventArgs e)
{
int closepaymentmng = closepaymentmanager();
const int WM_USER = 0x0400;
msgmntr = new MessageMonitorEventHandler(MessageMonitor_MessageReceived);
MessageMonitor.MessageReceived += msgmntr;
MessageMonitor.WatchMessage(0x3B9);
hndle = MessageMonitor.WindowHandle;
int openpaymentmng = openpaymentmanager();
int startpaymentmnh = startpaymentmanager(hndle, 0x3B9, 0, 0, 0);
long setpaymentmng = setpaymentmanager(0, 0, 0, 0);
textBoxprice.Text = "0";
textBoxpaid.Text = "0";
}
public void MessageMonitor_MessageReceived(IntPtr hwnd, int message, IntPtr wParam, IntPtr lParam)
{
Console.WriteLine(string.Format ("message:{0} , wparam= {1} ,lparam = {2}", message,wParam,lParam));
if (wParam.ToString() == "17")
{
textBoxpaid.Text = (Convert.ToDecimal( textBoxpaid.Text)+ Convert.ToDecimal( lParam.ToString())/100).ToString();
}
if (wParam.ToString() == "18")
{
textBoxpaid.Text = (Convert.ToDecimal(textBoxpaid.Text) + Convert.ToDecimal(lParam.ToString()) / 100).ToString();
}
if (wParam.ToString() == "33")
{
textBoxpaid.Text = (Convert.ToDecimal(textBoxpaid.Text) - Convert.ToDecimal(lParam.ToString()) / 100).ToString();
}
}
, sucess. , -, .