我正在开发一个在 Windows Mobile 6 上运行的 C# 应用程序,因此是 .NET Compact Framework。它使用后台线程来处理网络通信并保持 UI 空闲。
这些线程在对象内(作为另一个项目的一部分编写)。主应用程序实例化对象,并告诉他们开始连接。所有的线程控制都是由'connection'对象完成的。
当应用程序通过菜单退出时,它调用 connection.Stop() 方法,该方法告诉连接对象断开连接,释放其资源并关闭线程。这一切都很好,但是如果应用程序从任务管理器中被终止,或者通过从“正在运行的程序”下拉列表中点击“X”,则应用程序的主 GUI 会关闭,但这些对象已启动的线程不会。
使用设备上的第 3 方任务管理器,我可以看到“正在运行的应用程序”下没有应用程序的迹象,但它在“正在运行的进程”下以与应用程序相同的二进制文件列出。我尝试重新启动应用程序,然后它在屏幕上轻弹,然后再次关闭。
我如何捕捉应用程序关闭的事件,捕捉表单关闭不是我想要做的 - 无论如何,Closing 事件似乎都不会触发。
我在线程上设置了 isBackgroundWorker 但这没有效果。
如果我无法捕获正在关闭的应用程序,我将如何让线程检查应用程序的 UI 是否仍然存在,如果不存在则关闭。
**我在输入此内容时遇到了一些问题。如果主应用程序被杀死并且它的对象被释放,那么这些对象由主应用程序实例化。这会让这些线程陷入困境吗?我应该在“连接”对象的 onDispose 中清除它们吗?
编辑- 根据要求添加代码,这些是我认为相关的片段,应用程序很大。这是在主应用程序内
public Connection = new Connection(id, server, port, onStatusChange);
this.Connection.Start();
onStatusChange is a delegate on the main app
在连接对象中.. Connection.Start() 看起来像;
public void Start()
{
//Since we can't check the thread state then we have to kill the existing thread
Stop();
//Should not be able to start a new thread if one is already running
lock (this.pushLock)
{
ConnectionThreadStart = new ThreadStart(ConnectionThreadMethod);
ConnectionThread = new Thread(ConnectionThreadStart);
ConnectionThread.Name = "Connection";
ConnectionThread.IsBackground = true;
//Start the new thread
this.start = true;
ConnectionThread.Start();
}
}
/// <summary>
/// Method ran by the connection thread
/// </summary>
private void ConnectionThreadMethod()
{
//Take ownership of ConnectionThread until we exit
lock (this.pushLock)
{
//Keep trying to connect until flag tells us not to
while (this.start)
{
//establish and maintain connection
}
}
}
public void Stop()
{
//Indicate to thread that it should not continue running.
this.start = false;
//Attempt to close the socket on which the connection listens, this should cause it to fail with an exception
try
{
Socket.Client.Close();
}
catch(Exception e)
{
}
try
{
Socket.Close();
}
catch(Exception e)
{
}
//If for some reason the thread is still going ask it to abort which, again, should cause it to throw an exception and exit
try
{
ConnectionThread.Abort();
}
catch(Exception e)
{
}
//Finally join the thread if it is still going and wait for it to exit. It will give up waiting after 10 seconds
try
{
if (!ConnectionThread.Join(10000))
{
//The thread failed to stop, we can do no more, the thing is borken
}
}
catch (Exception e)
{
}
}
因此,当应用程序正常退出时,我只需调用 Connection.Stop() 并关闭它。
进一步编辑;- 添加了这个..仍然没有像我预期的那样做。
private bool disposed = false;
//Implement IDisposable.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
Stop();
}
disposed = true;
}
}
~Connection()
{
// Simply call Dispose(false).
Dispose (false);
}
}