Hey everyone,
I've got a problem that is driving me up a wall and I was hoping that someone here might be able to offer a little insight. I've written a handfull of SimConnect apps using C# and I have noticed something a bit odd of late. All of the apps are written using the same basic structure but some, not all, are throwing exceptions when FSX exits while the app is still running. An AccessViolationException is being thrown from the ReceiveMessages method.
Here's a short sample that is throwing it now:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.FlightSimulator.SimConnect;
using System.Runtime.InteropServices;
namespace TestFoo1
{
public partial class Form1 : Form
{
SimConnect simconnect;
const int WM_USER_SIMCONNECT = 0x0402;
public Form1()
{
InitializeComponent();
}
private void button_Connect_Click(object sender, EventArgs e)
{
if (simconnect == null)
{
try
{
simconnect = new SimConnect("Test", this.Handle, WM_USER_SIMCONNECT, null, 0);
textBox_Connect.Text = "Connecting...";
simconnect.OnRecvOpen += new SimConnect.RecvOpenEventHandler(simconnect_OnRecvOpen);
simconnect.OnRecvQuit += new SimConnect.RecvQuitEventHandler(simconnect_OnRecvQuit);
}
catch (COMException ex)
{
textBox_Connect.Text = "Unable to Connect";
}
}
else
{
textBox_Connect.Text = "Disconnected";
button_Connect.Text = "Connect";
simconnect.Dispose();
simconnect = null;
}
}
void simconnect_OnRecvQuit(SimConnect sender, SIMCONNECT_RECV data)
{
textBox_Connect.Text = "Disconnected";
button_Connect.Text = "Connect";
simconnect.Dispose();
simconnect = null;
}
void simconnect_OnRecvOpen(SimConnect sender, SIMCONNECT_RECV_OPEN data)
{
textBox_Connect.Text = "Connected to FSX";
button_Connect.Text = "Disconnect";
}
protected override void DefWndProc(ref Message m)
{
if (m.Msg == WM_USER_SIMCONNECT)
{
if (simconnect != null)
{
simconnect.ReceiveMessage();
}
}
else
{
base.DefWndProc(ref m);
}
}
}
}
Here is the stacktrace I get when I exit FSX while the connection is open:
{System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at SimConnect_CallDispatch(Void* , IntPtr , Void* )
at Microsoft.FlightSimulator.SimConnect.SimConnect.ReceiveDispatch(SignalProcDelegate pfcnSignal)
at Microsoft.FlightSimulator.SimConnect.SimConnect.ReceiveMessage()
at TestFoo1.Form1.DefWndProc(Message& m) in E:\My Documents\Visual Studio 2005\Projects\TestFoo1\TestFoo1\Form1.cs:line 71
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ContainerControl.WndProc(Message& m)
at System.Windows.Forms.Form.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 TestFoo1.Program.Main() in E:\My Documents\Visual Studio 2005\Projects\TestFoo1\TestFoo1\Program.cs:line 17
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()}
I can avoid this exception in favor of a COMException if I remove the Dispose call in OnRecvQuit. Obviously, I could just catch either of these exceptions and get on with my life, but my obsessive compulsive disorder won't seem to let me move on without at least an explanation.
For reference, I'm running XP SP2, FSX SP1a and VS2005.
It seems like some kind of race condition problem, but I'm not able to sort out a way around this or explain the specifics of it.
Thoughts?
JG
I've got a problem that is driving me up a wall and I was hoping that someone here might be able to offer a little insight. I've written a handfull of SimConnect apps using C# and I have noticed something a bit odd of late. All of the apps are written using the same basic structure but some, not all, are throwing exceptions when FSX exits while the app is still running. An AccessViolationException is being thrown from the ReceiveMessages method.
Here's a short sample that is throwing it now:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.FlightSimulator.SimConnect;
using System.Runtime.InteropServices;
namespace TestFoo1
{
public partial class Form1 : Form
{
SimConnect simconnect;
const int WM_USER_SIMCONNECT = 0x0402;
public Form1()
{
InitializeComponent();
}
private void button_Connect_Click(object sender, EventArgs e)
{
if (simconnect == null)
{
try
{
simconnect = new SimConnect("Test", this.Handle, WM_USER_SIMCONNECT, null, 0);
textBox_Connect.Text = "Connecting...";
simconnect.OnRecvOpen += new SimConnect.RecvOpenEventHandler(simconnect_OnRecvOpen);
simconnect.OnRecvQuit += new SimConnect.RecvQuitEventHandler(simconnect_OnRecvQuit);
}
catch (COMException ex)
{
textBox_Connect.Text = "Unable to Connect";
}
}
else
{
textBox_Connect.Text = "Disconnected";
button_Connect.Text = "Connect";
simconnect.Dispose();
simconnect = null;
}
}
void simconnect_OnRecvQuit(SimConnect sender, SIMCONNECT_RECV data)
{
textBox_Connect.Text = "Disconnected";
button_Connect.Text = "Connect";
simconnect.Dispose();
simconnect = null;
}
void simconnect_OnRecvOpen(SimConnect sender, SIMCONNECT_RECV_OPEN data)
{
textBox_Connect.Text = "Connected to FSX";
button_Connect.Text = "Disconnect";
}
protected override void DefWndProc(ref Message m)
{
if (m.Msg == WM_USER_SIMCONNECT)
{
if (simconnect != null)
{
simconnect.ReceiveMessage();
}
}
else
{
base.DefWndProc(ref m);
}
}
}
}
Here is the stacktrace I get when I exit FSX while the connection is open:
{System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at SimConnect_CallDispatch(Void* , IntPtr , Void* )
at Microsoft.FlightSimulator.SimConnect.SimConnect.ReceiveDispatch(SignalProcDelegate pfcnSignal)
at Microsoft.FlightSimulator.SimConnect.SimConnect.ReceiveMessage()
at TestFoo1.Form1.DefWndProc(Message& m) in E:\My Documents\Visual Studio 2005\Projects\TestFoo1\TestFoo1\Form1.cs:line 71
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ContainerControl.WndProc(Message& m)
at System.Windows.Forms.Form.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 TestFoo1.Program.Main() in E:\My Documents\Visual Studio 2005\Projects\TestFoo1\TestFoo1\Program.cs:line 17
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()}
I can avoid this exception in favor of a COMException if I remove the Dispose call in OnRecvQuit. Obviously, I could just catch either of these exceptions and get on with my life, but my obsessive compulsive disorder won't seem to let me move on without at least an explanation.
For reference, I'm running XP SP2, FSX SP1a and VS2005.
It seems like some kind of race condition problem, but I'm not able to sort out a way around this or explain the specifics of it.
Thoughts?
JG

