【问题标题】:Multithread using backgroundworker and event handler使用 backgroundworker 和事件处理程序的多线程
【发布时间】:2016-11-23 02:03:15
【问题描述】:

我正在开发一个示例程序,以使用后台工作程序连接多个设备。每个连接的设备都将作为新对象添加到列表中。完成连接所有设备后,我想为每个连接的设备添加一个事件处理程序。我现在面临的问题是事件处理程序根本没有触发。以下是示例代码。

连接点击按钮事件:

private void btnConnect_Click(object sender, EventArgs e)
{
    using (BackgroundWorker m_oWorker = new BackgroundWorker())
    {
        m_oWorker.DoWork += delegate (object s, DoWorkEventArgs args)
        {
            int iIpStart = 0;
            int iIpEnd = 0;
            string strIp1 = string.Empty;
            string strIp2 = string.Empty;

            list.Clear();

            string[] sIP1 = txtIpStart.Text.Trim().ToString().Split('.');
            string[] sIP2 = txtIpEnd.Text.Trim().ToString().Split('.');

            iIpStart = Convert.ToInt32(sIP1[3]);
            iIpEnd = Convert.ToInt32(sIP2[3]);

            strIp1 = sIP1[0] + "." + sIP1[1] + "." + sIP1[2] + ".";
            strIp2 = sIP2[0] + "." + sIP2[1] + "." + sIP2[2] + ".";

            Ping ping = new Ping();
            PingReply reply = null;

            int iIncre = 0;
            int iVal = (100 / (iIpEnd - iIpStart));
            for (int i = iIpStart; i <= iIpEnd; i++)
            {
                Thread.Sleep(100);

                string strIpconnect = strIp1 + i.ToString();
                Console.Write("ip address : " + strIpconnect + ", status: ");
                reply = ping.Send(strIpconnect);

                if (reply.Status.ToString() == "Success")
                {
                    if (ConnectDevice(strIpconnect))
                    {
                        strLastDevice = strIpconnect + " Connected";
                        isconnected = true;
                    }
                    else
                    {
                        isconnected = false;
                    }
                }
                else
                {
                    isconnected = false;
                }
                m_oWorker.ReportProgress(iIncre);
                iIncre = iIncre + iVal;
            }
            m_oWorker.ReportProgress(100);
        };
        m_oWorker.ProgressChanged += new ProgressChangedEventHandler(m_oWorker_ProgressChanged);
        m_oWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(m_oWorker_RunWorkerCompleted);
        m_oWorker.WorkerReportsProgress = true;
        m_oWorker.WorkerSupportsCancellation = true;

        m_oWorker.RunWorkerAsync();
    }
}

ConnectDevice 函数方法。连接的设备将被添加到列表中:

protected bool ConnectDevice(string sIP)
{
    try
    {
        NewSDK sdk = new NewSDK();

        if (sdk.Connect() == true)
        {
            list.Add(new objSDK { sdk = sdk, ipaddress = sIP });
            return true;
        }
        else
        {

        }
    }
    catch() {}
    return false;
}

后台工作者:

void m_oWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    //If it was cancelled midway
    if (e.Cancelled)
    {
        lblStatus.Text = "Task Cancelled.";
    }
    else if (e.Error != null)
    {
        lblStatus.Text = "Error while performing background operation.";
    }
    else
    {
        lblStatus.Text = "Task Completed...";
        btnListen.Enabled = true;
    }
}

void m_oWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    //Here you play with the main UI thread
    progressBar1.Value = e.ProgressPercentage;
    lblStatus.Text = "Processing......" + progressBar1.Value.ToString() + "%";

    if (isconnected)
    {
        listBox2.Items.Add(strLastDevice);
        string[] ssplit = sDeviceInfo.Split(';');

        foreach (string sword in ssplit)
        {
            listBox1.Items.Add(sword);
        }
    }
}

附加事件的功能:

private void RegisterEvent()
{
    foreach (objSDK obj in list)
    {
        obj.sdk.OnTransaction += () =>
        {
            listBox1.Items.Add("ip : " + obj.IP + " transaction");
        };
    }
}

【问题讨论】:

  • 我想你说的是 OnTransaction 事件。但是我看不到您在这些 sn-ps 中的任何地方提出事件。也许是我疲惫的老眼睛,但它确实符合抱怨。 ProgressChanged 事件处理程序有问题,strLastDevice 变量不是线程安全的。请改用 ReportProgress(int, object) 重载。
  • @hans-passant 我在单击按钮时引发了事件..我有另一个按钮可以与后台工作人员分开附加事件

标签: c# multithreading winforms backgroundworker


【解决方案1】:

您已将m_oWorker 声明为局部变量。我猜这是个错误(m_ 前缀只能用于类成员变量)?

此外,您在 using 语句中声明了它,这意味着框架将在 using 块的末尾对其调用 Dispose()。即使你坚持对它的引用(我不认为你这样做),它仍然意味着它的资源将被释放,这可能就是它不处理任何事件的原因。

【讨论】:

  • 以前我使用m_oWorker 作为类成员变量,而没有使用using 语句。结果是一样的。
【解决方案2】:

我通过使用线程和任务尝试了另一种解决方法,并且工作正常。感谢大家的回复

【讨论】:

  • 您应该详细说明您的解决方案。这还不是真正的答案。可能这对找到这篇文章的其他人非常有帮助。这对我来说值得一票
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-08
  • 1970-01-01
  • 2012-04-28
  • 2016-02-07
  • 1970-01-01
相关资源
最近更新 更多