Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当应用程序被Windows Mobile 6.x杀死时清理后台线程_C#_Multithreading_Windows Mobile_Compact Framework - Fatal编程技术网

C# 当应用程序被Windows Mobile 6.x杀死时清理后台线程

C# 当应用程序被Windows Mobile 6.x杀死时清理后台线程,c#,multithreading,windows-mobile,compact-framework,C#,Multithreading,Windows Mobile,Compact Framework,我正在开发一个运行在WindowsMobile6上的C#应用程序,即.NETCompactFramework。它使用后台线程来处理网络通信并保持用户界面自由 这些线程位于对象内(作为另一个项目的一部分写入)。主应用程序实例化对象,并告诉它们启动连接。所有线程控制都由“connection”对象完成 当应用程序通过菜单退出时,它调用connection.Stop()方法,该方法告诉连接对象断开连接,释放其资源并关闭线程。这一切都很好,但是,如果应用程序是从任务管理器中终止的,或者通过从“运行程序”

我正在开发一个运行在WindowsMobile6上的C#应用程序,即.NETCompactFramework。它使用后台线程来处理网络通信并保持用户界面自由

这些线程位于对象内(作为另一个项目的一部分写入)。主应用程序实例化对象,并告诉它们启动连接。所有线程控制都由“connection”对象完成

当应用程序通过菜单退出时,它调用connection.Stop()方法,该方法告诉连接对象断开连接,释放其资源并关闭线程。这一切都很好,但是,如果应用程序是从任务管理器中终止的,或者通过从“运行程序”下拉列表中点击“X”来终止的,那么应用程序的主GUI将关闭,但由这些对象启动的线程不会关闭

使用设备上的第三方任务管理器,我可以看到在“正在运行的应用程序”下没有应用程序的迹象,但在“正在运行的进程”下,它与应用程序的二进制文件相同。我尝试重新启动该应用程序,然后它会弹到屏幕上,然后再次关闭

如何捕捉应用程序关闭的事件,捕捉表单关闭并不是我想要做的事情-关闭事件似乎无论如何都不会触发

我已经在线程上设置了isBackgroundWorker,但没有效果

如果我无法捕获正在关闭的应用程序,我将如何让线程检查应用程序的UI是否仍然存在,如果不存在则关闭

**我在打这个的时候有一个想法。。如果主应用程序被终止并且其“对象”被释放,则这些对象由主应用程序实例化。。这是不是让这些线处于边缘?我应该在'connection'对象的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)
        {
        }
    }

如果应用程序通过任务管理器强制终止,则您的托管应用程序无法享受运行清理代码的乐趣。它只是被终止,停在它的轨道上,不管它在做什么。如果你能看到它仍然在运行,这可能是由于一个较低级别的司机拒绝让步。如果看不到这些线程在做什么,就不可能确定地知道

如果您通过WM“running processes”实用程序终止应用程序,我相信会在您的表单窗口中发布一条
WM_QUIT
消息,因此您确实有机会正确处理它并在退出前进行清理

要处理诸如意外退出请求之类的事件,您应该在
应用程序.Run()
周围放置一个try/finally块。finally块中的代码将在每次应用程序正常关闭时执行,因此是编写此类清理例程的理想位置

下面是一些伪代码,描述了它的外观:

            try
        {
            //application startup code here//


            System.Windows.Forms.Application.Run(new YourMainForm());
        }

        catch (Exception x)
        {
            log.Fatal("FATAL application exception occurred.", x);
           //TODO: decide how to handle fatal exception. Feedback to user?

        }

        finally
        {
            try
            {
                //shut down application activities 
                //shutdown your connection object here                  
            }
            catch (Exception ex)
            {
                log.Error("A fatal error occurred while attempting to shutdown the application", ex);

            }
        }

如果应用程序通过任务管理器强制终止,则您的托管应用程序无法享受运行清理代码的乐趣。它只是被终止,停在它的轨道上,不管它在做什么。如果你能看到它仍然在运行,这可能是由于一个较低级别的司机拒绝让步。如果看不到这些线程在做什么,就不可能确定地知道

如果您通过WM“running processes”实用程序终止应用程序,我相信会在您的表单窗口中发布一条
WM_QUIT
消息,因此您确实有机会正确处理它并在退出前进行清理

要处理诸如意外退出请求之类的事件,您应该在
应用程序.Run()
周围放置一个try/finally块。finally块中的代码将在每次应用程序正常关闭时执行,因此是编写此类清理例程的理想位置

下面是一些伪代码,描述了它的外观:

            try
        {
            //application startup code here//


            System.Windows.Forms.Application.Run(new YourMainForm());
        }

        catch (Exception x)
        {
            log.Fatal("FATAL application exception occurred.", x);
           //TODO: decide how to handle fatal exception. Feedback to user?

        }

        finally
        {
            try
            {
                //shut down application activities 
                //shutdown your connection object here                  
            }
            catch (Exception ex)
            {
                log.Error("A fatal error occurred while attempting to shutdown the application", ex);

            }
        }

你有密码吗。。?如果我们看不到您现有的代码,就很难帮助他人。谢谢按要求添加一些代码示例。谢谢。最干净的解决方案是使用waithandle来阻止应用程序的退出,直到退出代码发出信号。问题可能是你的代码没有等待线程退出。啊,这里有一个有趣的链接指向这个主题:即使应用程序被任务管理器杀死,或者在运行程序列表中点击“关闭”,它还会等待吗。如果通过应用程序中的“退出”按钮退出,则应用程序退出的方式没有问题。您是否有任何代码。。?如果我们看不到您现有的代码,就很难帮助他人。谢谢按要求添加一些代码示例。谢谢。最干净的解决方案是使用waithandle来阻止应用程序的退出,直到退出代码发出信号。问题可能是你的代码没有等待线程退出。啊,这里有一个有趣的链接指向这个主题:即使应用程序被任务管理器杀死,或者在运行程序列表中点击“关闭”,它还会等待吗。如果通过应用程序中的“退出”按钮退出,则应用程序退出的方式没有问题。