2014-01-22 84 views
0

我有一個相當複雜的情況,實際上結合了我的代碼的一些嵌套條件:處理複雜條件的逆

Sub RunWorkload() 
    If iisSvr1rstdone = True And (iisSvr2rstdone = True Or utilnamespace.iisSvr2 = "") And (rptSvrrstdone = True Or utilnamespace.rptSvr = "") And (Workload.chkCache.Checked = False Or sqlSvrrstdone = True) Then 
     Workload.txtStatus.Text = "Running Workload..." 
     <more things happen> 
    End If 
End Sub 

我的問題是,由於代碼是正確的,現在寫的,它只是打響評估一次,這根本行不通。這些done變量中的每一個都是一個布爾值,它被填充爲「我完成了!」的一部分。事件。因此,如果目前沒有填充,它應該定期重新評估。

這使我想到我現在有這樣一個問題:我在考慮用While更換If,但是這將涉及編寫該條件的倒數,所以像:

While iisSvr1rstdone = False And (iisSvrrstdone = False or utilnamespace.iisSvr IsNot Nothing) And (rptSvrrstdone = False or utilnamespace.rptSvr IsNot Nothing) And (Workload.chkCache.Checked = True or sqlSvrrstdone = True) 

,我可以循環瀏覽直到它評估爲True。我的問題是,它似乎...太複雜了,我害怕我錯過了一些可以簡化它的東西。我的另一個想法是將If語句的結果作爲一個單獨的函數存儲,以便我可以讓While語句不斷運行該函數,直到它的計算結果爲true。

我是否錯過了任何會使此概念點擊的內容?

+0

當您調用'RunWorkload'時,是否希望它等到滿足所有條件,然後<使事情發生>?或者如果滿足條件,則調用'RunWorkload'並且只有<使事情發生>? – djv

+1

另外,從布爾表達式中刪除'= True'和'= False'會使它看起來不那麼複雜。 – djv

+0

它需要等到所有條件都滿足爲止。布爾值都默認爲False(我將它們聲明爲False,然後將它們切換爲True)。 –

回答

1

,最簡單的方法來 「反向」 布爾語句是使用

If Not (a=b) Then 

,而不是

If a=b Then 

我注意到,在你的代碼的最後部分

(Workload.chkCache.Checked = False Or sqlSvrrstdone = sqlSvrrstdone = True) 

沒有任何意義,因爲Or之後的部分永遠是真的,所以整個事情永遠是真的那麼,因爲它是連接到其餘的將使整個事情不必要的。也許這是你的代碼中的一個錯誤,或者你可以刪除整個事情。 要手動反轉這些語句,您將用= False替換所有= True,用And替換Or,反之亦然。所以這將是

If iisSvr1rstdone = False Or _ 
    (iisSvr2rstdone = False And utilnamespace.iisSvr2 <> "") Or _ 
    (rptSvrrstdone = False And utilnamespace.rptSvr <> "") Then 

這應該做你的if語句的反例,如果我沒有搞砸了。我之前提到的不必要的部分從此刪除。

對這種類型的代碼使用單獨的函數總是一個好主意,因爲它使代碼更具可讀性。

+0

啊,這是一個錯字。我編輯了我的代碼。你也是對的。最後一點是不必要的代碼。 –

1

我會做一個等待條件不滿足的方法。爲了更好的可讀性,我將它們分成了單獨的塊。 Async/Await允許UI線程繼續處理其他事件,或者您可以直接通過調用waitForServersReady來阻止它。

Private iisSvr1rstdone, iisSvr2rstdone, rptSvrrstdone, sqlSvrrstdone, WorkloadchkCacheChecked As Boolean 
Private utilnamespaceiisSvr2, utilnamespacerptSvr, WorkloadtxtStatusText As String 

Private Sub waitForServersReady() 
    While Not iisSvr1rstdone 
     System.Threading.Thread.Sleep(1) 
    End While 
    While Not (iisSvr2rstdone Or utilnamespaceiisSvr2 = "") 
     System.Threading.Thread.Sleep(1) 
    End While 
    While Not (rptSvrrstdone Or utilnamespacerptSvr = "") 
     System.Threading.Thread.Sleep(1) 
    End While 
    While Not (WorkloadchkCacheChecked Or sqlSvrrstdone) 
     System.Threading.Thread.Sleep(1) 
    End While 
End Sub 

Async Sub RunWorkload() 
    Await Task.Factory.StartNew(AddressOf waitForServersReady) 
    ' you can also just waitForServersReady() 
    WorkloadtxtStatusText = "Running Workload..." 
End Sub 
+0

啊,我明白了。這樣做的好處是,當這些任務完成時,我的UI線程可以繼續做其他事情。聰明,我從來沒有使用過這樣的等待或異步處理(以前的迭代只是一個控制檯應用程序,所以它更簡單一些)。謝謝! –

+0

@SeanLong我會去掉'= True',因爲'True = True'這個語句是多餘的,而'True'完成這項工作。 – djv

+0

另一種可能性是使用SELECT CASE TRUE並在每個CASE測試一個條件。 – rheitzman