.net 关闭时从工作线程保存会话

.net 关闭时从工作线程保存会话,.net,vb.net,multithreading,thread-safety,.net,Vb.net,Multithreading,Thread Safety,我有一个多线程的VB.net程序。我想循环每个线程,从每个线程获取会话 下面是创建线程的代码 Sub Run(): Timer1.Enabled = True AddHandler LoginTimer.Elapsed, AddressOf doWork LoginTimer.Interval = 500 LoginTimer.Enabled = True End Sub 这是道工潜水艇: sub doWork() For id = 0 to val(t

我有一个多线程的VB.net程序。我想循环每个线程,从每个线程获取会话

下面是创建线程的代码

Sub Run():
    Timer1.Enabled = True
    AddHandler LoginTimer.Elapsed, AddressOf doWork
    LoginTimer.Interval = 500
    LoginTimer.Enabled = True
End Sub
这是道工潜水艇:

sub doWork()
    For id = 0 to val(textbox1.text) ' get how many thread should we run
                Dim th As New Thread(AddressOf Work) ' what the threads should do.
                th.IsBackground = True
                th.Start()
    Next id
现在,每次我关闭程序时,线程都会中止,并且我丢失了那些线程一直在处理的所有内容。所以,我想保存会话。下次运行时,我只需通过加载会话来“恢复”它。比如:

Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
    Dim sessions As New List(Of String)
    For Each thread In xxxx ' here where should I do a loop through the running threads
       sessions.Add(thread.session) ' get the session from the thread
    Next thread 
End Sub
提前谢谢


编辑:我已经通过创建一个公共共享的ShoulIupadteNow作为Boolean来修复我的问题,因为我的线程是在连续循环中运行的,它们一直在检查Boolean是否设置为true。如果是,我通常在表单上单击一个按钮将其设置为true,它会通过将一个公共共享的lstsessions作为新的hashsetof string开始更新。这样,我就不会有重复的会话,并且一旦所有线程完成更新,我会遍历hashset中的所有内容,然后将其存储在txt文件中。

如果您的问题是保存来自每个线程的内容您可以将所需的数据保存在调用每个线程的顶级类中的公共变量中。例如,在类GUI中有一个名为controlador的类。这个类处理其他线程。当有其他线程的信息要传递给类GUI时,我将这些信息保存在controlador属性中,然后通过类GUI调用这些属性。我不知道我是否把自己说清楚了。唯一的问题是,如果要从其他线程之一更新类GUI内的控件。如果这是您的情况,您应该在GUI类中有如下方法:

Delegate Sub SetDebugLabel_Delegate(ByVal lbl As Label, ByVal text As String)

Public Sub SetDebugLabel_ThreadSafe(ByVal lbl As Label, ByVal text As String)
    If lbl.InvokeRequired Then
            Dim MyDelegate As New SetDebugLabel_Delegate(AddressOf SetDebugLabel_ThreadSafe)
            Me.Invoke(MyDelegate, New Object() {lbl, text})
    Else
        lbl.Text = text
    End If
End Sub
然后您应该在do work sub中使用如下内容:

 SetDebugLabel_ThreadSafe(Me.lblDataServer, ctrl.dTempo)
    Dim settings As XmlWriterSettings = New XmlWriterSettings()
    settings.Indent = True


Using writer As XmlWriter = XmlWriter.Create(caminho & "alarmes.xml", settings)

   ' Begin writing.
     writer.WriteStartDocument()
     writer.WriteStartElement("CNCO") ' Root.

     With Login.user.DB1.dsDados.Tables("Lista")
         For i As Integer = 0 To .Rows.Count - 1
              writer.WriteStartElement("Duto")
              writer.WriteElementString("Nome", "Alarmes")
              writer.WriteElementString("TAG", .Rows(i)("TAG"))
              writer.WriteEndElement()
         Next

         ' End document.
         writer.WriteEndElement()
         writer.WriteEndDocument()

    End With
 End Using
 With Login.user.DB1.dsDados
          .Tables("Lista").Clear()
          .ReadXml(arquivo)
          .Tables(0).DefaultView.Sort = "TAG DESC"
 End With
其中,ctrl是实例化的controlador类

如果您喜欢XML方法,可以将所需的数据保存到datatable中,然后导出为XML

在中可以看到一种方法,或者您可以这样做:

 SetDebugLabel_ThreadSafe(Me.lblDataServer, ctrl.dTempo)
    Dim settings As XmlWriterSettings = New XmlWriterSettings()
    settings.Indent = True


Using writer As XmlWriter = XmlWriter.Create(caminho & "alarmes.xml", settings)

   ' Begin writing.
     writer.WriteStartDocument()
     writer.WriteStartElement("CNCO") ' Root.

     With Login.user.DB1.dsDados.Tables("Lista")
         For i As Integer = 0 To .Rows.Count - 1
              writer.WriteStartElement("Duto")
              writer.WriteElementString("Nome", "Alarmes")
              writer.WriteElementString("TAG", .Rows(i)("TAG"))
              writer.WriteEndElement()
         Next

         ' End document.
         writer.WriteEndElement()
         writer.WriteEndDocument()

    End With
 End Using
 With Login.user.DB1.dsDados
          .Tables("Lista").Clear()
          .ReadXml(arquivo)
          .Tables(0).DefaultView.Sort = "TAG DESC"
 End With
要读取XML,只需读取路径arquivo是路径字符串,并将数据恢复到datatable中。有一种方法可以这样做:

 SetDebugLabel_ThreadSafe(Me.lblDataServer, ctrl.dTempo)
    Dim settings As XmlWriterSettings = New XmlWriterSettings()
    settings.Indent = True


Using writer As XmlWriter = XmlWriter.Create(caminho & "alarmes.xml", settings)

   ' Begin writing.
     writer.WriteStartDocument()
     writer.WriteStartElement("CNCO") ' Root.

     With Login.user.DB1.dsDados.Tables("Lista")
         For i As Integer = 0 To .Rows.Count - 1
              writer.WriteStartElement("Duto")
              writer.WriteElementString("Nome", "Alarmes")
              writer.WriteElementString("TAG", .Rows(i)("TAG"))
              writer.WriteEndElement()
         Next

         ' End document.
         writer.WriteEndElement()
         writer.WriteEndDocument()

    End With
 End Using
 With Login.user.DB1.dsDados
          .Tables("Lista").Clear()
          .ReadXml(arquivo)
          .Tables(0).DefaultView.Sort = "TAG DESC"
 End With

当你关闭应用程序时,它就完成了。如果您需要它在下一次启动时恢复操作,您需要将您的“会话”持久化到一个更永久的存储区,例如SQL数据库或XML文件。这正是我要做的。但是,如何将这些会话连接到SQL数据库或XML。我需要从正在运行的线程中获取它们,然后保存它们。对不起,您模拟的内容有点模糊,所以我的答案也有点笼统。。。一个起点是在工作方法开始时将线程化的对象写入表,并在工作结束时将其删除。当这些线程正在运行时关闭窗体时,未删除的线程将成为待处理队列。然后,Form_Load或其他适当的地方可以加载上一次关闭中的剩余/废弃记录,并对其进行处理,完成后删除每个记录。我正在考虑在form1中创建一个公共共享列表,然后不断更新它。但是它会消耗更多的CPU,这正是我一直在研究的,使程序更加轻量级。所以这是我的B计划,以防没有人知道怎么做:既然没有人回答,而且我已经设法解决了我的问题,我会把你的答案标记为正确的。我将编辑我的帖子,提及我如何修复它: