0

我有一个按钮,它启动程序和称为 DDC 的机器之间的连接。为了防止在建立连接时UI线程被锁定,我自然而然地创建了一个backgroundworker来处理这个工作。

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

如果单击程序上的按钮,我希望用户能够取消操作,但据我所知,没有办法中止 backgroundworker 并且取消不会真正帮助我,因为线程被锁定在代码甚至可以检查 cancelpending 是否为真之前 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);
        }

    }
4

1 回答 1

3

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

您可以通过与第一个BackgroundWorker一起运行的第二个来解决您的问题,它只在第一个中轮询一个标志以验证其状态:由于他是独立的,它不必“等待”并且可以自由杀死第一个工人以防万一它卡住了。

这应该是无死锁的,因为只要标志处理指令包含在lock.

流程看起来像这样:

  • 当您需要连接时,启动两个工作人员
  • 第一个工作人员继续尝试连接,设置一个标志以通知外部世界其“连接”状态
  • 第二个工作人员可能每秒钟检查第一个工作人员状态 30 次:如果它从不读取与“连接”不同的任何内容,它可以继续并杀死第一个工作人员。它还可能对用户输入做出反应并在时间之前杀死第一个工人(即,任何用户输入都会取消第二个工人,这反过来又可以在第一个工人自己死亡之前杀死第一个工人)。
  • 流程结束
于 2012-07-17T08:23:55.810 回答