Async และ Await เหตุใดจึงส่งคืนค่าสองค่า

ฉันกำลังพยายามคิดอยู่ Async and Await มันไปได้ดี แต่สิ่งหนึ่งที่ฉันต้องการชี้แจงคือเหตุใดจึงมีคำสั่ง return สองคำสั่งในวิธีการของฉัน ฉันกำลังมองหาคำอธิบายเกี่ยวกับสิ่งที่เกิดขึ้นจริงเบื้องหลัง

ฉันจะโพสต์โค้ดแบบเต็มด้านล่างเนื่องจากมีประมาณ 80 บรรทัดเท่านั้น ฉันกำลังพูดถึงวิธีกลาง AllSubfolderFiles ซึ่งมีทั้ง Return counter และ Return dirsFraction เกิดอะไรขึ้นกับสิ่งเหล่านี้จริงๆ?

โดยพื้นฐานแล้ว มันเป็นแอปพลิเคชัน WinForm ที่วนซ้ำไฟล์ทั้งหมดของโฟลเดอร์ย่อย โดยอัปเดต ProgressBar สำหรับแต่ละโฟลเดอร์ย่อยที่วนซ้ำ

Imports System.IO

Public Class frmAsyncProgress

    Private Sub frmAsyncProgress_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        barFileProgress.Minimum = 0
        barFileProgress.Maximum = 100
        btnCancel.Enabled = False
    End Sub

    Private Async Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click
        If String.IsNullOrWhiteSpace(txtPath.Text) Then
            MessageBox.Show("Provide a location first.", "Location")
            Exit Sub
        End If
        Dim sLocation As String = txtPath.Text.Trim()
        If Not Directory.Exists(sLocation) Then
            MessageBox.Show("Directory doesn't exist.", "Location")
            Exit Sub
        End If

        Dim progressIndicator = New Progress(Of Integer)(AddressOf UpdateProgress)
        btnStart.Enabled = False
        btnCancel.Enabled = True
        lblPercent.Text = "0%"

        Dim allFiles As Integer = Await AllSubfolderFiles(sLocation, progressIndicator)
        Debug.WriteLine(allFiles.ToString())        'the number of subfolders iterated
        btnStart.Enabled = True
        btnCancel.Enabled = False
    End Sub

    Private Async Function AllSubfolderFiles(location As String, progress As IProgress(Of Integer)) As Task(Of Integer)
        Dim dirsTotal As Integer = Directory.GetDirectories(location).Length
        Dim dirsFraction As Integer = Await Task(Of Integer).Run(Function()
                                                                     Dim counter As Integer = 0
                                                                     For Each subDir As String In Directory.GetDirectories(location)
                                                                         SubfolderFiles(subDir)
                                                                         counter += 1
                                                                         If progress IsNot Nothing Then
                                                                             progress.Report(counter * 100 / dirsTotal)
                                                                         End If
                                                                     Next

                                                                     Return counter
                                                                 End Function)
        Return dirsFraction
    End Function

    Private Sub UpdateProgress(value As Integer)
        barFileProgress.Value = value
        lblPercent.Text = (value / 100).ToString("#0.##%")
    End Sub

    Private Sub SubfolderFiles(location As String)
        'source: http://stackoverflow.com/questions/16237291/visual-basic-2010-continue-on-error-unauthorizedaccessexception#answer-16237749

        Dim paths = New Queue(Of String)()
        Dim fileNames = New List(Of String)()

        paths.Enqueue(location)

        While paths.Count > 0
            Dim sDir = paths.Dequeue()

            Try
                Dim files = Directory.GetFiles(sDir)
                For Each file As String In Directory.GetFiles(sDir)
                    fileNames.Add(file)
                Next

                For Each subDir As String In Directory.GetDirectories(sDir)
                    paths.Enqueue(subDir)
                Next
            Catch ex As UnauthorizedAccessException
                ' log the exception or ignore it
                Debug.WriteLine("Directory {0}  could not be accessed!", sDir)
            Catch ex As Exception
                ' log the exception or ...
                Throw
            End Try
        End While
        'could return fileNames collection
    End Sub
End Class

การประเมินของฉันคือ counter ถูกส่งคืนแล้วจึงรวมกลับไปที่เธรด UI เป็น dirsFraction แต่ฉันไม่มั่นใจกับคำอธิบายที่ฉันพยายามทำ

ป้อนคำอธิบายรูปภาพที่นี่


person Andy G    schedule 14.02.2016    source แหล่งที่มา


คำตอบ (1)


ภายในฟังก์ชัน AllSubfolderFiles ของคุณ คุณเรียกใช้ Task.Run และส่งผ่านฟังก์ชันที่ไม่ระบุตัวตนซึ่งส่งคืนด้วย Return counter AllSubfolderFiles รอผลลัพธ์ของการโทรนั้นแล้วกลับมาพร้อมกับ Return dirsFraction

ดังนั้น คุณมีผลตอบแทน 2 รายการในฟังก์ชันเดียวกัน เนื่องจากคุณมีฟังก์ชันที่ไม่ระบุตัวตนภายในฟังก์ชันเดิม คุณสามารถย้ายฟังก์ชันนั้นออกไปที่ฟังก์ชันที่มีชื่อของตัวเองได้ ซึ่งจะทำให้ชัดเจนยิ่งขึ้นว่ามีฟังก์ชันที่แตกต่างกัน 2 ฟังก์ชันที่นี่

person i3arnon    schedule 14.02.2016
comment
ขอบคุณมาก ฟังดูสมเหตุสมผลดี (ฉันเกือบไปแล้ว ;) ) - person Andy G; 14.02.2016