代码卡在 BackgroundWorker

Posted

技术标签:

【中文标题】代码卡在 BackgroundWorker【英文标题】:Code getting stuck in BackgroundWorker 【发布时间】:2014-03-17 16:34:43 【问题描述】:

我遇到了 BackgroundWorker 卡住的问题。 已经投入了大量的 console.writeline 来帮助尝试缩小问题所在的范围,但速度很快。

我注意到在返回输出时,我收到了这条消息... 线程 0x2d68 已退出,代码为 259 (0x103)

谁能告诉我这是什么意思?

编辑 - 下面是我的完整代码。 提供一些背景知识,此应用程序正在处理从网站收到的请求,以在云环境中部署虚拟机。

它对前几项工作正常,但随后卡在“BuildProgressCheck”BackgroundWorker 中。

然后它停止处理任何更多的项目,并且 BuildProgressCheck Backgroundworker isbusy 坚持为真。

任何帮助,我一直在尝试解决这个问题。 :(

谢谢!

    Imports mysql.Data.MySqlClient
    Imports System
    Imports System.IO
    Imports System.Xml
    Imports System.Net.Mail
    Imports System.Text
    Imports System.Diagnostics



    Public Class Home
        Public dbserver As String
Public dbusername As String
Public dbpassword As String
Public dbdatabase As String
Public appdebug As String
Public appconfig As String
Public jobcheckresult As String = "jobcheckresult"
Public buildchecktickid As Integer = 0
Public jobchecktickid As Integer = 0
Public new_vm_jobid As String
Public new_vm_state As String
Public new_vm_ipaddress As String
Public new_vm_macaddress As String
Public new_vm_hostname As String
Public new_vm_cpunumber As String
Public new_vm_cpuspeed As String
Public new_vm_memory As String
Public new_vm_netmask As String
Public new_vm_gateway As String
Public new_vm_templatename As String
Public new_vm_instancename1 As String
Public job_check_status As String
Public jobcheckstatusid As String
Public new_vm_success_internal_email As String
Public new_vm_fail_internal_email As String
Public new_vm_success_external_email As String
Public new_vm_processing_internal_email As String
Public internal_email_recipient As String
Public internal_email_sender As String
Public internal_mail_server As String
Public internal_mail_server_username As String
Public internal_mail_server_password As String
Public logentrytext As String
Public logdirectory As String = "C:\CloudPlatform\"
Public logpath As String = logdirectory & "dbcpman_log.txt"
Public logappend As Boolean = True
Public ccnl = ControlChars.NewLine
Public cpapiurl As String = "http://192.168.16.221:8081/client/api?"
Public cpapikey As String = "apiKey=YUsTgg_d6QB9KhdjYS6K314t9BZhL0B3T-DHR1vm8BrkF2pv2qqx698Vzb8O-srSOAKYa0nYB8qLQdXjaKHefQ"
Public buildcheckactive As Integer = 0       ' 0=false, 1=true '
Public buildprogresscheckactive As Integer = 0       ' 0=false, 1=true '
Public jobcheckactive As Integer = 0         ' 0=false, 1=true '

Public Sub login_Shown(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Shown

    Control.CheckForIllegalCrossThreadCalls = False
            Dim config As String = "cloudcommander.conf"

    If System.IO.File.Exists(config) = True Then
        Dim objReader As New System.IO.StreamReader(config)
        appconfig = objReader.ReadToEnd
        objReader.Close()
        Dim configlines() As String = appconfig.Split(vbCrLf)
        For Each line As String In configlines
            ' MessageBox.Show(configlines)
        Next

        dbserver = configlines(1)
        dbserver = Replace(dbserver, "server=", "")
        dbdatabase = configlines(2)
        dbdatabase = Replace(dbdatabase, "database=", "")
        dbusername = configlines(3)
        dbusername = Replace(dbusername, "userid=", "")
        dbpassword = configlines(4)
        dbpassword = Replace(dbpassword, "password=", "")


        Else
        lblstatus.Text = "Configuration Error"""
        MsgBox("Could not locate configuration file " & ControlChars.NewLine & ControlChars.NewLine & "This program may not work correctly   :(")
    End If
    lblstatus.Text = "Configuration is fine - moving along..."


    Dim cn As New MySqlConnection
    cn.ConnectionString = "server=" & dbserver & "; userid=" & dbusername & "; password=" & dbpassword & "; database=" & dbdatabase & ";Convert Zero Datetime=True"
    Dim jobcheck As New MySqlDataAdapter("Select * FROM dbcpman_jobs WHERE failed='false'", cn)
    Dim jobcheck_table As New DataTable
    jobcheck.Fill(jobcheck_table)

    Dim row As DataRow
    For Each row In jobcheck_table.Rows
        Dim strDetail As String
        strDetail = row("dbxid")
        buildpendinglist.Items.Add(strDetail)
        logentrytext = "[STARTUP] Found pending job for import: " & strDetail
        Call dbcpman_log(logentrytext, logdirectory, logpath, logappend)        ''''''Do some logging
    Next row

        Try

            logentrytext = "[JOB-CALLBACK] API response: " & jobcheckresult
            Call dbcpman_log(logentrytext, logdirectory, logpath, logappend)        ''''''Do some logging

        Catch ex As Exception

        End Try

    BuildWorkerTimer.Start()
    BuildProgressCheckTimer.Start()

End Sub

Private Sub NewItemCheck_Tick(sender As Object, e As EventArgs) Handles BuildWorkerTimer.Tick

    buildchecktickid = buildchecktickid + 1
    countbuilds.Text = buildcheckactive
    countjobs.Text = buildprogresscheckactive

    If BuildWorker.IsBusy Then
        Beep()
    Else
        BuildWorker.RunWorkerAsync()
    End If

End Sub

Private Sub BuildProgressCheckTimer_Tick(sender As Object, e As EventArgs) Handles BuildProgressCheckTimer.Tick

    Console.WriteLine("Timer 'BuildProgressCheckTimer'.... TICK!")
    Dim bpc_busy_count As Integer = 0

    If BuildProgressCheck.IsBusy Then
        Beep()
        bpc_busy_count = bpc_busy_count + 1
        If bpc_busy_count > 4 Then
            Beep()
            Beep()
            BuildProgressCheck.CancelAsync()
        End If
    Else
        BuildProgressCheck.RunWorkerAsync()
    End If

End Sub

Private Sub BuildWorker_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BuildWorker.DoWork


    lblstatus.Text = "Checking for new requests"
    buildcheckactive = 1
    Dim cn As New MySqlConnection
    cn.ConnectionString = "server=" & dbserver & "; userid=" & dbusername & "; password=" & dbpassword & "; database=" & dbdatabase & ";Convert Zero Datetime=True"
    Dim vmcheck As New MySqlDataAdapter("Select * FROM dbcpman_vm WHERE deployrequired='true' ", cn)
    Dim vmcheck_table As New DataTable
    vmcheck.Fill(vmcheck_table)
    Dim row As DataRow
    row = vmcheck_table.Select("deployrequired = 'true'").FirstOrDefault()

    If Not row Is Nothing Then

        Dim new_vm_id As String = row.Item("id")
        Dim new_vm_account As String = row.Item("account")
        Dim new_vm_name As String = row.Item("name")
        Dim new_vm_displayname As String = row.Item("displayname")
        Dim new_vm_memory As String = row.Item("memory")
        Dim new_vm_cpuspeed As String = row.Item("cpuspeed")
        Dim new_vm_cpunumber As String = row.Item("cpunumber")
        Dim new_vm_group As String = row.Item("vmgroup")
        Dim new_vm_instancename As String = row.Item("instancename")
        Dim new_vm_diskofferingid As String = row.Item("diskofferingid")
        Dim new_vm_disksize As String = row.Item("customdisksize")
        Dim new_vm_serviceofferingid As String = row.Item("serviceofferingid")
        Dim new_vm_serviceofferingname As String = row.Item("serviceofferingname")
        Dim new_vm_publicip As String = row.Item("publicip")
        Dim new_vm_os As String = row.Item("OS")
        Dim new_vm_templateid As String = row.Item("templateid")
        Dim dbx_id As String = row.Item("dbx_id")
        Dim new_job_status As String = "NEW"
        dbx_id = dbx_id & new_vm_id

        Try
            Dim myCommand As New MySqlCommand
            Dim myAdapter As New MySqlDataAdapter
            Dim SQL As String
            myCommand.Connection = cn
            cn.Open()
            myAdapter.SelectCommand = myCommand
            SQL = "UPDATE dbcpman_vm SET dbx_id = '" & dbx_id & "' WHERE id = '" & new_vm_id & "'"
            myCommand.CommandText = SQL
            myCommand.ExecuteNonQuery()
            cn.Close()
        Catch ex As Exception
            MessageBox.Show("ERROR3 " & ccnl & ccnl & ex.Message)
        End Try

        buildpendinglist.Items.Add(dbx_id)

        Dim commandstring As String = "command=deployVirtualMachine" _
                                      & "&ServiceOfferingId=" & new_vm_serviceofferingid _
                                      & "&size=" & new_vm_disksize _
                                      & "&templateId=" & new_vm_templateid _
                                      & "&zoneid=1" _
                                      & "&displayname=" & new_vm_displayname _
                                      & "&name=" & new_vm_name _
                                      & "&instancename=" & new_vm_instancename _
                                      & "&internalname=" & new_vm_displayname

        Dim fullapiurl = cpapiurl & commandstring
        Try
            Dim myCommand As New MySqlCommand
            Dim myAdapter As New MySqlDataAdapter
            Dim SQL As String
            myCommand.Connection = cn
            cn.Open()
            myAdapter.SelectCommand = myCommand
            SQL = "UPDATE dbcpman_vm SET deployrequired = 'false' WHERE id = '" & new_vm_id & "'"
            myCommand.CommandText = SQL
            myCommand.ExecuteNonQuery()
            cn.Close()

        Catch ex As Exception
            MessageBox.Show("ERROR2 " & ccnl & ccnl & ex.Message)
        End Try


        Try
            Dim webClient As New System.Net.WebClient
            Dim result As String = webClient.DownloadString(fullapiurl)

            Dim doc As New System.Xml.XmlDocument
            doc.LoadXml(result)
            Dim new_vm_jobidxml = doc.GetElementsByTagName("jobid")

            For Each item As System.Xml.XmlElement In new_vm_jobidxml

                new_vm_jobid = item.ChildNodes(0).InnerText()
                Dim myCommand As New MySqlCommand
                Dim myAdapter As New MySqlDataAdapter
                Dim SQL As String
                myCommand.Connection = cn
                cn.Open()
                myAdapter.SelectCommand = myCommand
                SQL = "UPDATE dbcpman_vm SET deploy_jobid = '" & new_vm_jobid & "' WHERE id = '" & new_vm_id & "'"
                myCommand.CommandText = SQL
                myCommand.ExecuteNonQuery()

                SQL = "UPDATE dbcpman_vm SET deploycompleted = 'false' WHERE id = '" & new_vm_id & "'"
                myCommand.CommandText = SQL
                myCommand.ExecuteNonQuery()

                SQL = "INSERT into dbcpman_jobs(jobid, status, dbxid) VALUES ('" & new_vm_jobid & "','" & new_job_status & "','" & dbx_id & "')"
                myCommand.CommandText = SQL
                myCommand.ExecuteNonQuery()
                cn.Close()
                'MessageBox.Show("ADDED ITEM TO JOBS")
            Next

        Catch ex As Exception
            MessageBox.Show("ERROR1 " & ccnl & ccnl & ex.Message)
        End Try
    End If

    new_vm_jobid = ""
    new_vm_state = ""
    new_vm_ipaddress = ""
    new_vm_macaddress = ""
    new_vm_hostname = ""
    new_vm_cpunumber = ""
    new_vm_cpuspeed = ""
    new_vm_memory = ""
    new_vm_netmask = ""
    new_vm_gateway = ""
    new_vm_templatename = ""
    new_vm_instancename1 = ""
    buildcheckactive = 0

End Sub





    Private Sub BuildProgressCheck_DoWork(sender As Object, e As ComponentModel.DoWorkEventArgs) Handles BuildProgressCheck.DoWork

    Dim i As Integer
    For i = 0 To buildpendinglist.Items.Count - 1

        Dim cn As New MySqlConnection
        cn.ConnectionString = "server=" & dbserver & "; userid=" & dbusername & "; password=" & dbpassword & "; database=" & dbdatabase & ";Convert Zero Datetime=True"
        Dim jobcheck As New MySqlDataAdapter("Select * FROM dbcpman_jobs WHERE dbxid='" & buildpendinglist.Items(i) & "'", cn)
        Dim jobcheck_table As New DataTable
        jobcheck.Fill(jobcheck_table)
        Dim jobrow As DataRow
        jobrow = jobcheck_table.Select("failed = 'false'").FirstOrDefault()

        If Not jobrow Is Nothing Then

            Dim job_id As String = jobrow.Item("id")
            Dim job_jobid As String = jobrow.Item("jobid")
            Dim job_status As String = jobrow.Item("status")
            Dim job_dbxid As String = jobrow.Item("dbxid")
            Dim jobcommand As String = "command=queryAsyncJobResult&jobId=" & job_jobid
            Dim fulljobapicheckurl = cpapiurl & jobcommand

            Try
                Dim jobapicall As New System.Net.WebClient
                jobcheckresult = jobapicall.DownloadString(fulljobapicheckurl)
            Catch ex As Exception
                Console.WriteLine("Error 'DBX-Err-1' - Error during API call")
            End Try


            If jobcheckresult.Contains("<jobstatus>1</jobstatus>") Then  ''If true, job has completed
                Console.WriteLine(job_dbxid & "Is completed")
                Dim doc As New System.Xml.XmlDocument
                doc.LoadXml(jobcheckresult) ''api_result contains xml returned from a http request.

                Try
                    Console.WriteLine("Entering XML Parse...")
                    If doc.GetElementsByTagName("virtualmachine") IsNot Nothing Then
                        Dim elem As XmlNodeList = doc.GetElementsByTagName("virtualmachine").Item(0).ChildNodes
                        For Each item As XmlNode In elem
                            If item.Name.Equals("state") Then
                                new_vm_state += ((item.InnerText.ToString()) + Environment.NewLine)
                            ElseIf item.Name.Equals("hostname") Then
                                new_vm_hostname += ((item.InnerText.ToString()) + Environment.NewLine)
                            ElseIf item.Name.Equals("templatename") Then
                                new_vm_templatename += ((item.InnerText.ToString()) + Environment.NewLine)
                            ElseIf item.Name.Equals("cpunumber") Then
                                new_vm_cpunumber += ((item.InnerText.ToString()) + Environment.NewLine)
                            ElseIf item.Name.Equals("cpuspeed") Then
                                new_vm_cpuspeed += ((item.InnerText.ToString()) + Environment.NewLine)
                            ElseIf item.Name.Equals("memory") Then
                                new_vm_memory += ((item.InnerText.ToString()) + Environment.NewLine)
                            ElseIf item.Name.Equals("nic") Then
                                new_vm_netmask += ((item.ChildNodes.Item(3).InnerText.ToString()) + Environment.NewLine)
                                new_vm_gateway += ((item.ChildNodes.Item(4).InnerText.ToString()) + Environment.NewLine)
                                new_vm_ipaddress += ((item.ChildNodes.Item(5).InnerText.ToString()) + Environment.NewLine)
                                new_vm_macaddress += ((item.ChildNodes.Item(11).InnerText.ToString()) + Environment.NewLine)
                            ElseIf item.Name.Equals("instancename") Then
                                new_vm_instancename1 += ((item.InnerText.ToString()) + Environment.NewLine)
                            End If
                            Console.WriteLine("Finished XML parse")
                        Next
                    End If
                Catch ex As Exception
                    Console.WriteLine("Error 'DBX-Err-2' - Error parsing returned XML string")
                End Try


                new_vm_macaddress = new_vm_macaddress.ToUpper
                Console.WriteLine("Replacing chars from int IP")
                Dim privateip As String = new_vm_ipaddress.Replace(" ", "").ToString
                Dim publicip As String = privateip.Replace("172.16.11.", "196.15.17.")
                Console.WriteLine("IP formatted correctly")

                Try
                    Console.WriteLine("Entering SQL Try...")
                    Dim myCommand As New MySqlCommand
                    Dim myAdapter As New MySqlDataAdapter
                    Dim SQL As String
                    myCommand.Connection = cn
                    cn.Open()
                    myAdapter.SelectCommand = myCommand
                    SQL = "DELETE FROM dbcpman_jobs WHERE jobid = '" & job_jobid & "'"
                    myCommand.CommandText = SQL
                    myCommand.ExecuteNonQuery()
                    Console.WriteLine("removed job from dbcpman_jobs")
                    SQL = "UPDATE dbcpman_vm SET deployresponse = '" & jobcheckresult & "' WHERE dbx_id = '" & job_dbxid & "'"
                    myCommand.CommandText = SQL
                    myCommand.ExecuteNonQuery()
                    Console.WriteLine("updated deployresponse in dbcpman_vm")
                    SQL = "UPDATE dbcpman_vm SET macaddress = '" & new_vm_macaddress & "' WHERE dbx_id = '" & job_dbxid & "'"
                    myCommand.CommandText = SQL
                    myCommand.ExecuteNonQuery()
                    Console.WriteLine("Updated macaddress in dbcpman_vm")
                    SQL = "UPDATE dbcpman_vm SET publicip = '" & publicip & "' WHERE dbx_id = '" & job_dbxid & "'"
                    myCommand.CommandText = SQL
                    myCommand.ExecuteNonQuery()
                    Console.WriteLine("updated publicIP in dbcpman_vm")
                    SQL = "UPDATE dbcpman_vm SET privateip = '" & privateip & "' WHERE dbx_id = '" & job_dbxid & "'"
                    myCommand.CommandText = SQL
                    myCommand.ExecuteNonQuery()
                    Console.WriteLine("updated privateIP in dbcpman_vm")

                    cn.Close()
                    Console.WriteLine("DB connection closed")

                    Dim new_vm_username As String = "clouduser"
                    Dim new_vm_password As String = GeneratePassword(7)
                    Console.WriteLine("clouduser password generated")
                    new_vm_password = new_vm_password & "oX7" ''''will remove this once generator can ensure complex passwords
                    System.Threading.Thread.Sleep(1000)
                    Dim new_vm_support_username As String = "dbxsupport"
                    Dim new_vm_support_password As String = GenerateSupportPassword(7)
                    Console.WriteLine("dbxsupport password generated")
                    new_vm_support_password = new_vm_support_password & "Kw3" ''''will remove this once generator can ensure complex passwords

                    cn.Open()
                    Console.WriteLine("Database connection opened")
                    myAdapter.SelectCommand = myCommand
                    SQL = "INSERT into dbcpman_credentials(username1, username2, password1, password2, type, link) VALUES ('" & new_vm_username & "','" & new_vm_support_username & "','" & new_vm_password & "','" & new_vm_support_password & "','Server root logon','" & job_dbxid & "')"
                    myCommand.CommandText = SQL
                    myCommand.ExecuteNonQuery()
                    Console.WriteLine("Saved credentials to dbcpman_credentials")
                    SQL = "INSERT into dbcpman_vm_boot(dbxid, ip, macaddress, hostname) VALUES ('" & job_dbxid & "','" & new_vm_ipaddress & "','" & new_vm_macaddress & "','" & job_dbxid & "')"
                    myCommand.CommandText = SQL
                    myCommand.ExecuteNonQuery()
                    Console.WriteLine("added VM tags to dbcpman_vm_boot")
                    cn.Close()
                    Console.WriteLine("Closed SQL connection")

                    Try  ''''add monitoring for this host
                        Console.WriteLine("3 - Adding monitoring for " & job_dbxid)
                        Dim monitorurl As String = "http://192.168.16.32/addhost.php?hostname=" & job_dbxid & "&ipaddr=" & publicip
                        Dim webClient As New System.Net.WebClient
                        Dim monresult As String = webClient.DownloadString(monitorurl)
                        Console.WriteLine("Request sent to add monitoring")
                        If monresult = "SUCCESS" Then
                            Console.WriteLine("Monitoring added")
                        Else
                            Console.WriteLine("Unable to add monitoring")

                        End If
                    Catch ex As Exception
                        Console.WriteLine("Error 'DBX-Err-3' - Error adding monitoring")
                    End Try

                    buildcompletedlist.Items.Add(buildpendinglist.Items(i))
                    Console.WriteLine("Item removed from pending list")
                    buildpendinglist.Items.Remove(buildpendinglist.Items(i))
                    Console.WriteLine("Item added to complete list")

                Catch ex As Exception
                    MessageBox.Show("ERROR- C " & ccnl & ccnl & ex.Message)
                End Try

            ElseIf jobcheckresult.Contains("<jobstatus>0</jobstatus>") Then  ''If true, job is still pending
                Console.WriteLine("Checking on pending job " & buildpendinglist.Items(i) & "...")




            ElseIf jobcheckresult.Contains("<jobstatus>2</jobstatus>") Then  ''If true, job has failed
                Try
                    Console.WriteLine("An item has failed")
                    Dim myCommand As New MySqlCommand
                    Dim myAdapter As New MySqlDataAdapter
                    Dim SQL As String
                    myCommand.Connection = cn
                    cn.Open()
                    myAdapter.SelectCommand = myCommand
                    SQL = "UPDATE dbcpman_jobs SET failed = 'true' WHERE jobid = '" & job_jobid & "'"
                    myCommand.CommandText = SQL
                    myCommand.ExecuteNonQuery()
                    Console.WriteLine("updated Failed in dbcpman_jobs")
                    cn.Close()

                    buildfailedlist.Items.Add(buildpendinglist.Items(i))
                    Console.WriteLine("Item remove from pending list")
                    buildpendinglist.Items.Remove(buildpendinglist.Items(i))
                    Console.WriteLine("Item added to failed list")
                    Try
                        Console.WriteLine("Trying to send email notifying support of a failure...")
                        Dim Errorbody As String = "Hi, " & ccnl & ccnl & "CloudCommander encountered a problem whilst deploying a VM and attention is required." & _
                            ccnl & ""
                        Dim SmtpServer As New SmtpClient()
                        Dim mail As New MailMessage()
                        SmtpServer.Credentials = New  _
                        Net.NetworkCredential(internal_mail_server_username, internal_mail_server_password)
                        SmtpServer.Port = 25
                        SmtpServer.Host = internal_mail_server
                        mail = New MailMessage()
                        mail.From = New MailAddress("autoattendant@cloud.net")
                        mail.To.Add("support@cloud.net")
                        mail.Subject = "[CLOUDFAIL] A cloud server has failed to deploy"
                        mail.Body = Errorbody
                        SmtpServer.Send(mail)
                        Console.WriteLine("Mail sent.")
                    Catch ex As Exception
                        Console.WriteLine("Mail failed to send.")
                    End Try

                Catch ex As Exception

                End Try

            End If
        End If
        Console.WriteLine("HEADING FOR THE NEXT ITEM")
        Console.WriteLine("###################################################")
    Next
    buildprogresscheckactive = 0

    Console.WriteLine("Done with async jobcheck for this pass")




End Sub
Private Sub JobWorker_DoWork(sender As Object, e As ComponentModel.DoWorkEventArgs) Handles JobWorker.DoWork

End Sub




Private Sub buildpendinglist_SelectedIndexChanged(sender As Object, e As EventArgs) Handles buildpendinglist.DoubleClick

    ItemDetails.Show()
End Sub

【问题讨论】:

一些代码怎么样。正在处理什么? 签出this。 编辑了原始帖子以包含完整的代码 - 感谢大家的帮助 【参考方案1】:

线程 ... 已退出,代码为 259 (0x103)

这是VS2013中的一个已知bug,反馈报告is here。这没有任何意义,而且这个错误是良性的,它不会影响 BackgroundWorker 的执行方式。该错误已修复,总有一天它会出现在您的机器上。不知道什么时候。

【讨论】:

以上是关于代码卡在 BackgroundWorker的主要内容,如果未能解决你的问题,请参考以下文章

在区分源代码,对象代码,汇编代码和机器代码时,我有一个困惑

PHP代码没有被执行,但代码显示在浏览器源代码中

PHP代码没有被执行,但代码显示在浏览器源代码中

PHP代码没有被执行,但代码显示在浏览器源代码中

代码块:在Java中用{}括起来的代码

ubuntu 在哪里输入代码