私は、Windows Mobile 6 で実行される C# アプリケーションに取り組んでいるので、.NET Compact Framework です。バックグラウンド スレッドを使用してネットワーク通信を処理し、UI を解放します。
これらのスレッドはオブジェクト内にあります (別のプロジェクトの一部として記述されています)。メイン アプリはオブジェクトをインスタンス化し、接続を開始するように指示します。すべてのスレッド制御は「接続」オブジェクトによって行われます。
アプリがメニューから終了すると、connection.Stop() メソッドを呼び出します。このメソッドは、接続オブジェクトに切断を指示し、そのリソースを解放して、スレッドをシャットダウンします。これは問題ありませんが、アプリがタスク マネージャーから強制終了された場合、または [実行中のプログラム] ドロップダウンから [X] を押した場合、アプリのメイン GUI は閉じますが、これらのオブジェクトによって開始されたスレッドは閉じません。
デバイスでサードパーティのタスク マネージャーを使用すると、「実行中のアプリケーション」の下にアプリの兆候がないことがわかりますが、「実行中のプロセス」の下にはアプリケーションと同じバイナリが表示されています。アプリケーションを再起動しようとすると、画面にフリックしてから再びオフになります。
アプリが閉じられているイベントをキャッチするにはどうすればよいですか。フォームを閉じることをキャッチすることは、私が探していることではありません。とにかく 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);
}
}