2016-02-14 75 views
0

我試圖讓我的頭在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://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,但我不是我試圖解釋說服。

enter image description here

回答

2

裏面你AllSubfolderFiles函數調用Task.Run,並通過在與Return counter返回一個匿名函數。 AllSubfolderFiles等待該呼叫的結果,然後用Return dirsFraction返回。

因此,您在同一個函數中有兩個返回值,因爲您的原始函數中有一個匿名函數。你可以將這個函數移動到它自己命名的函數中,這會使得它更清晰,這裏有兩個不同的函數。

+0

非常感謝,這是有道理的(我幾乎在那裏;))。 –