异步和等待,为什么两个返回值

问题描述:

我试图让我的头在Async and Await左右。这很顺利,但我想澄清的一件事是为什么我的方法中有两个返回语句。我真的在寻找关于幕后实际发生的事情的解释。异步和等待,为什么两个返回值

我将发布下面的完整代码,因为它只有大约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://*.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,但我不是我试图解释说服。

enter image description here

里面你AllSubfolderFiles函数调用Task.Run,并通过在与Return counter返回一个匿名函数。 AllSubfolderFiles等待该呼叫的结果,然后用Return dirsFraction返回。

因此,您在同一个函数中有两个返回值,因为您的原始函数中有一个匿名函数。你可以将这个函数移动到它自己命名的函数中,这会使得它更清晰,这里有两个不同的函数。

+0

非常感谢,这是有道理的(我几乎在那里;))。 –