需要从具有此编码样式的线程获取返回值

时间:2014-10-23 14:02:17

标签: vb.net multithreading begininvoke

我的测试表明,在代码队列中排列10个theads并同时运行其中的3个。没关系。但我无法从课堂上获得回报价值。

在终止程序之前,Finalize事件永远不会触发。它奇怪,因为我希望线程结束,它会自动摧毁自己。但事实并非如此。

我看到我需要使用委托函数来实现这一点,但是我无法使用委托使用此队列示例。

任何人都可以帮助我获得回调函数内的返回值吗?我疯了,显然我的知识还不够。

Imports System.ComponentModel
Imports System.Threading
Public Class Form1
    Private tasks As New Queue(Of Action)
    Private RunningThread As Integer
    Private Lock As New Object
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnButton1.Click
        Dim i As Integer
        For i = 1 To 10
            Dim w As New Work()
            w.Data = i
            Dim Task As New Action(AddressOf w.DoWork)
            If RunningThread < 3 Then
                Task.BeginInvoke(AddressOf Callback, Nothing)
                Threading.Interlocked.Increment(RunningThread)
                Console.WriteLine(i.ToString & " basladi")
            Else
                Console.WriteLine(i.ToString & " bekliyor")
                SyncLock (Lock)
                    tasks.Enqueue(Task)
                End SyncLock
            End If
        Next
    End Sub
    Private Sub Callback(ByVal o As Object)
        If tasks.Count > 0 Then
            Dim Task As Action
            SyncLock (Lock)
                Task = tasks.Dequeue
            End SyncLock
            Task.BeginInvoke(AddressOf Callback, Nothing)
        Else
            Threading.Interlocked.Decrement(RunningThread)
        End If
    End Sub
End Class

这是我打电话的非常简单的课程。

Public Class Work
    Public Data As Integer
    Public Function DoWork() As String
        Console.WriteLine(Data.ToString & " inside class")
        Thread.Sleep(1000)
        Return Data.ToString & " output parameter"
    End Function
    Protected Overrides Sub Finalize()
        Console.WriteLine(Data.ToString & " this code never runs until form close.")
        MyBase.Finalize()
    End Sub
End Class

注意:这是目前正在运行的代码。

1 个答案:

答案 0 :(得分:0)

  1. Work.Finalize在终止之前不会运行,因为在完成后不会破坏局部变量w。在重新分配变量期间,由垃圾收集器管理Finalize。你想用它做什么?也许您应该使用其他解决方案。

  2. Button1_Click中的代码无法捕获Work.DoWork的回复。我使用Tasks.Task(Of String)代替Action,将它们全部放入1个列表进行处理。

  3. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Dim i As Integer
        For i = 1 To 10
            Dim w As New Work()
            w.Data = i
            Dim t = Tasks.Task(Of String).Factory.StartNew(AddressOf w.DoWork)
            RunningTasks.Add(t)
        Next
    
        i = 0
        For Each t In RunningTasks
            i = i + 1
            Console.WriteLine(String.Format("Task {0} completed with value: {1}", i, t.Result))
        Next
    End Sub

    输出:

    1 inside class
    3 inside class
    4 inside class
    2 inside class
    5 inside class
    7 inside class
    8 inside class
    6 inside class
    9 inside class
    Task 1 completed with value: 1 output parameter
    10 inside class
    Task 2 completed with value: 2 output parameter
    Task 3 completed with value: 3 output parameter
    Task 4 completed with value: 4 output parameter
    Task 5 completed with value: 5 output parameter
    Task 6 completed with value: 6 output parameter
    Task 7 completed with value: 7 output parameter
    Task 8 completed with value: 8 output parameter
    Task 9 completed with value: 9 output parameter
    Task 10 completed with value: 10 output parameter
    

    您还可以使用Action(Of String)并将BeginInvoke更改为: task.BeginInvoke(outputVariable, AddressOf Callback, Nothing)

    由于我不确定你想要对输出做什么,所以我不知道如何在回调中处理它。