我坚持维护的一些遗留代码陷入无限循环(因此我自己似乎在一个);我不知道为什么/怎么样。
这是应用程序的入口点,它实例化主窗体(frmCentral):
CODE EXHIBIT A
public static int Main(string [] args)
{
try
{
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(GlobalExceptionHandler);
string name = Assembly.GetExecutingAssembly().GetName().Name;
MessageBox.Show(string.Format("Executing assembly is {0}", name)); // TODO: Remove after testing <= this one is seen
IntPtr mutexHandle = CreateMutex(IntPtr.Zero, true, name);
long error = GetLastError();
MessageBox.Show(string.Format("Last error int was {0}", error.ToString())); // TODO: Remove after testing <= this one is also seen
if (error == ERROR_ALREADY_EXISTS)
{
ReleaseMutex(mutexHandle);
IntPtr hWnd = FindWindow("#NETCF_AGL_BASE_", null);
if ((int) hWnd > 0)
{
SetForegroundWindow(hWnd);
}
return 0;
}
MessageBox.Show("made it into Main method #4"); // TODO: Remove after testing <= this one is seen
ReleaseMutex(mutexHandle);
MessageBox.Show("made it into Main method #5"); // TODO: Remove after testing <= this one is seen
DeviceInfo devIn = DeviceInfo.GetInstance();
MessageBox.Show("made it into Main method #6"); // TODO: Remove after testing <= this one is seen
Wifi.DisableWifi();
MessageBox.Show("made it into Main method #7"); // TODO: Remove after testing <= this one is seen
// Instantiate a new instance of Form1.
frmCentral f1 = new frmCentral();
f1.Height = devIn.GetScreenHeight();
f1.Text = SSCS.GetFormTitle("SSCS HHS", "", "");
MessageBox.Show("made it before Application.Run() in Main method"); // TODO: Remove after testing <= this one is NOT seen
Application.Run(f1);
devIn.Close();
Application.Exit();
return 0;
}
catch(Exception ex)
{
SSCS.ExceptionHandler(ex, "Main");
return 0;
}
} // Main() method
frmCentral的构造函数然后调用一个名为 DBConnection.GetInstance()的单例方法(与glorified相反的是什么?):
CODE EXHIBIT B
public frmCentral()
{
try
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
MessageBox.Show("made it past InitializeComponent() in frmCentral constructor"); // <= this displays
devIn = DeviceInfo.GetInstance();
MessageBox.Show("made it past DeviceInfo.GetInstance() in frmCentral constructor"); // <= this displays
dbconn = DBConnection.GetInstance();
MessageBox.Show("made it past DBConnection.GetInstance() in frmCentral constructor");
WindowState = FormWindowState.Maximized;
UpdateMenuItemSelectable = false;
ResetConnectionFetchForm = false;
AllowNewItems = true;
listboxWork.Focus();
MessageBox.Show("made it through frmCentral constructor"); // <= this one does NOT display
}
catch (Exception ex)
{
SSCS.ExceptionHandler(ex, "frmCentral()");
}
} // frmCentral Constructor
这是“光荣的”单一/种类的单身方法:
CODE EXHIBIT C
// Singleton pattern, or at least a derivation thereof
public static DBConnection GetInstance()
{
MessageBox.Show("made it into DBConnection.GetInstance()");
try
{
if (instance == null)
{
MessageBox.Show("made it into DBConnection.GetInstance(); instance was null");
instance = new DBConnection();
}
}
catch(Exception ex)
{
SSCS.ExceptionHandler(ex, "DBConnection.GetInstance");
}
return instance;
}
实例化DBConnection,因此调用其构造函数:
CODE EXHIBIT D
private DBConnection()
{
try
{
// Connection String
string conStr = "Data Source = " + filename;
string cmpStr = conStr + ".tmp";
MessageBox.Show(string.Format("made it into DBConnection constructor. cmpStr == {0}", cmpStr)); // TODO: Comment out or remove
if (File.Exists(filename+".tmp"))
File.Delete(filename+".tmp");
engine = new SqlCeEngine(conStr);
MessageBox.Show(string.Format("SqlCeEngine created. conStr == {0}", conStr)); // TODO: Comment out or remove
if (File.Exists(filename))
{
MessageBox.Show(string.Format("file {0} exists", filename)); // TODO: Comment out or remove
}
else
{
// Create the SQL Server CE database
engine.CreateDatabase();
MessageBox.Show("Made it past call to engine.CreateDatabase()"); // TODO: Comment out or remove
}
engine.Dispose();
objCon = new SqlCeConnection(conStr);
MessageBox.Show("Made it past call to new SqlCeConnection(conStr)"); // TODO: Comment out or remove
objCon.Open();
}
catch(Exception ex)
{
SSCS.ExceptionHandler(ex, "DBConnection.DBConnection");
}
}
我从Code Exhibit A中看到* MessageBox.Show()* s(除非另有说明),然后代码图表B,然后是Code Exhibit C,然后是Code Exhibit D,然后它在C之间来回传递和D“直到奶牛回家。”
我不明白为什么DBConnection构造函数和DBConnection GetInstance()以递归方式相互调用,但是...我在大海捞针中是否有针,或是隐藏在普通视线中的大象,或者...... ???
public static void ExceptionHandler(Exception ex, string location)
{
try
{
MessageBox.Show("Exception: " + ex.Message + "\n\nLocation: " + location, GetFormTitle("SSCS: " + ex.GetType().FullName,"",""));
}
catch(Exception exc)
{
MessageBox.Show("Exception Handler generated an exception!\n" + exc.Message + "\n\nCalling Location: " + location, GetFormTitle("SSCS: " + exc.GetType().FullName,"",""));
}
}
这是更有启发性的晦涩:
public static string GetFormTitle(string formName, string serialNo, string siteNo)
{
string titleBar = formName == "" ? "SSCS HHS" : formName;
if((serialNo == ""))
{
User person = new User();
person.getUserFromTable();
serialNo = person.getSerialNo();
}
if (frmCentral.HashSiteMapping.ContainsKey(siteNo))
{
siteNo = (string) frmCentral.HashSiteMapping[siteNo];
}
if (serialNo != "")
titleBar += " - " + serialNo + (siteNo == "" ? "" : " Site #" + siteNo);
return titleBar;
}
我添加的未捕获的异常代码:
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(GlobalExceptionHandler);
static void GlobalExceptionHandler(object sender, UnhandledExceptionEventArgs args)
{
Exception e = (Exception)args.ExceptionObject;
MessageBox.Show(string.Format("GlobalExceptionHandler caught {0}; Compact Framework Version == {1}", e.Message, Environment.Version.ToString()));
}
我还没有看到任何证据表明此处理程序已经到达(无论如何,到目前为止)。
非常有趣 - 将一个MessageBox.Show(或两个)添加到GetFormTitle:
public static string GetFormTitle(string formName, string serialNo, string siteNo)
{
MessageBox.Show(string.Format("GetFormTitle() reached. formName == {0}; serialNo == {1}; siteNo == {2}", formName, serialNo, siteNo)); // TODO: Remove after testing
string titleBar = formName == "" ? "SSCS HHS" : formName;
if((serialNo == ""))
{
User person = new User();
person.getUserFromTable();
serialNo = person.getSerialNo();
}
if (frmCentral.HashSiteMapping.ContainsKey(siteNo))
{
siteNo = (string) frmCentral.HashSiteMapping[siteNo];
}
if (serialNo != "")
titleBar += " - " + serialNo + (siteNo == "" ? "" : " Site #" + siteNo);
MessageBox.Show(string.Format("titleBar val about to be returned. Val is {0}", titleBar)); // TODO: Remove after testing
return titleBar;
}
...这些是我现在看到的MessageBox.Show()的序列:
0) Made it into DBConnection.GetInstance()
1) Made it into DBConnection.GetInstance() instance was null
2) Made it to DBConnection constructor cmpStr == ....
3) Sqlceengine created. conStr == ...
4) File \My Documents\HHSDB.SDF exists
5) Made it past call to new SqlCeConnection(conStr)
6) GetFormTitle() reached. fromName == SSCS:
System.Data.SqlserverCe.SqlCeException; serial No ==; siteNo ==
...接下来是一轮追尾,递归的消息,直到我热身启动(我讨厌反对Fab 4,但与流行的观点相反,幸福绝对不是热情的启动!*)
...就在MessageBox消息显示中,插入了一个异常!全宾夕法尼亚嘻哈(Key Rap)!
* Let's have no attempts at humor revolving around warm booty, now!
这是远程桌面调试的最佳展示,LB2!
答案 0 :(得分:6)
以下是可能发生的事情(此时理论是OP可以确认的):
在图表D中,启动无限循环链的问题可能是objCon.Open();
。连接到数据库可能存在一些问题,Open()
调用应该抛出异常。这当然会被紧跟在该行之后的本地catch
中捕获。
更新1中显示的本地catch
调用SSCS.ExceptionHandler
。它看起来很温和,但在其中隐藏了罪魁祸首的帮凶,名称为GetFormTitle
,显示在更新2.
GetFormTitle
有一段非常有趣的代码:
User person = new User();
person.getUserFromTable();
...最有可能是从数据库中检索用户信息的模型(其他地方)。
好吧,要从数据库中获取User
,需要一个连接,这很可能会导致调用DBConnection.GetInstance()
,这会导致objCon.Open();
开始新的循环,因此创建infinite loop(巧妙地,不使用任何语言的内置循环机制,需要及时注明)。
OP:请在GetFormTitle
中放置非常简单的(意味着不要拨打GetFormTitle
MessageBoxes),如果上述理论是正确的,那么你就是&#39;我会在执行的路径中看到它。