需要关于在此背景工作者上实施取消的想法

时间:2012-07-17 08:09:41

标签: c# .net winforms multithreading backgroundworker

我有一个按钮,用于启动程序与称为DDC的计算机之间的连接。为了防止在建立连接时锁定UI线程,我自然会创建一个后台工作来处理这项工作。

问题是:如果客户端没有从DDC获得任何响应,则客户端必须等待30秒才能发出超时。更确切地说,线程停止在“GetLogicStatusListResponse result = ddcdao.GetLogicStatusList();”行上执行。

我希望用户能够取消操作,如果在程序上点击了一个按钮,但据我所知,没有办法中止后台工作,取消对我没有真正的帮助,因为在代码甚至可以检查取消是否为真之前,线程被锁定30秒。

我想听听一些正确实施取消功能的想法,以便用户可以随时启动/停止连接。

private void bwWorkerConnect_DoWork(object sender, DoWorkEventArgs e)
        {
            //Branch in only if the DDC returns a ping response
            if (DDCGlobal.DDCPingTest(ddc))
            {
                try
                {
                    //Creates an object of class which communicates with the engine
                    //Retrieves the object obtained through remoting (Engine) 
                    //and casts it to a ReqDDCLogicListResponse type (See CommonEngine)
                    DDCDAO ddcdao = new DDCDAO(DDCGlobal.ddcEngineIP, ddc.Ip);

                    //Request status list from DDC (TIMEOUT = 30 SECONDS)
                    GetLogicStatusListResponse result = ddcdao.GetLogicStatusList();
               ...
            if (bwWorkerConnect.CancellationPending)
            {
                e.Cancel = true;
            }



    public void LogicListLoad()
    {
        if (!bwWorkerConnect.IsBusy)
            bwWorkerConnect.RunWorkerAsync();
        else
        {
            MessageBox.Show(UIConstant.DDC_CONNECT_ALREADY_WARNING);
        }

    }

1 个答案:

答案 0 :(得分:3)

将我的评论作为答案发布以供将来参考。

您可以使用第一个BackgroundWorker与第一个lock一起运行来处理您的问题,在第一个中查看一个标志以验证其状态:由于他是独立的,因此不会必须“等待”,并且可以自由地杀死第一个工人,以免它被卡住。

这应该是无死锁的,因为第二个工作人员只做第一个工作人员的定期“健康检查”,只要标志处理指令包含在{{1}中}。

Flow会是这样的:

  • 当您需要连接时,启动两个工作人员
  • 第一个工作人员继续尝试连接,设置一个标志以通知外部世界其“连接”状态
  • 第二个工人可能每秒检查第一个工人状态30次:如果它从未读取任何与“连接”不同的东西,它可以继续并杀死第一个工人。它也可能对用户输入作出反应并在时间之前终止第一个工作者(即任何用户输入取消第二个工作者,这反过来可以在它自己死亡之前杀死第一个工作者)。
  • 流程结束