2009-08-27 87 views
1

有沒有什麼辦法可以停止另一個方法中的運行循環或者在C#中動態插入一個break語句?在C#中停止一個方法中的循環#

感謝

編輯:我希望能夠動態地攔截方法和插入休息的時候一個事件在另一個function.I被觸發有類的幾個實例,以停止循環,我想停下來無論何時需要循環,並管理所有實例。考慮多個實例是在一個通用的清單

例子:

List<myclass> objlist=new List<myclass>(); 

foreach(myclass obj in objlist) 
{ 
obj.loopingfunction().BreakLoop //or something like this (assuming that the loopingfunction is already called) 
} 

我需要這個,因爲我想打破一旦用戶存儲一些巨大的數據。當數量的用戶導入數據的循環,我得到一個事件。但我無法繼續從多個實例檢查數據庫,因爲它將sqlserver搞砸了。

這是在ASP.Net應用程序中。

回答

7

如果整個事情是在一個線程中運行,這將沒有任何意義。如果循環正在運行,則不會同時運行其他任何內容。如果你在另一個線程上運行一個循環,而在另一個線程上運行一個控制方法,你可以完全中止循環線程,或者檢查循環內部的一個標誌,以決定是否應該在控制方法中適當地中斷和設置標誌。

更新:使該函數返回一個布爾值,指示是否應該打破,並在「if」語句中使用它:

if (myFunctionShouldBreakLoop()) break; 
+0

在單線程的情況下,他的代碼可能是從循環內部調用的代理,在這種情況下,我可以看到他想要中斷循環的場景。這並不是說它變得更容易...... – 2009-08-27 04:54:57

+0

Franci:在這種情況下,它並不是真正的「動態」突破。基本上它只是輪詢另一種方法,並使用其返回值來查看它是否應該中斷。 – 2009-08-27 04:56:57

+0

問題是我無法檢查myFunctionShouldBreakLoop(),因爲....在我的情況下,該函數必須訪問數據庫並檢查用戶是否保存了數據。 – Josh 2009-08-27 05:02:28

2

在鎖定的屬性中有條件。

private Boolean BreakCondition 
{ 
    get { lock(_LockObject) { return _BreakCondition; } } 
    set { lock(_LockObject) { _BreakCondition = value; } } 
} 
private Boolean _BreakCondition = false; 
private Object _LockObject = new Object(); 


if (this.BreakCondition) 
{ 
    break; 
} 
+0

您可能希望鎖定該'if'爲好。 – Kobi 2009-08-27 05:01:55

+0

你是什麼意思? – ChaosPandion 2009-08-27 05:06:56

+0

這是非常無用的,訪問布爾值是原子的。 – 2009-08-27 06:32:42

1

我認爲你可以使用標誌

bool stop = false; 

for(int i=0;i<num;i++) 
{ 
if(stop) break; 
} 
3

另一種選擇是循環的每個迭代中提出一個CancelEventArgs。也許不是最有效的,但也可儘管如此:

private void SomeMethod() 
    { 
     for (int i = 0; i <= 100000; i++) 
     { 
      Console.WriteLine(i); 
      if (LoopIncrement != null) 
      { 
       CancelEventArgs args = new CancelEventArgs(); 
       LoopIncrement(null, args); 
       if (args.Cancel) 
       { 
        break; 
       } 
      } 
     } 

然後在別處:

myObj.LoopIncrement += MyHandler; 

private void MyHandler(object sender, CancelEventArgs e) 
{ 
    if(someCondition) 
    { 
     e.Cancel = true; 
    } 
} 

這樣,您就可以在一定程度控制來自外部的循環....

1

簡短的回答沒有。如果你不控制代碼,那麼你不能導致循環終止。

如果你控制的代碼,你可以建立某種合作的,但它聽起來混亂。也許你可以詳細說明爲什麼?

2

如何使用迭代器,併產生魔法來解決問題。

這裏是無限列表的文章,可能是有用的

http://www.codethinked.com/post/2009/02/04/Infinite-Lists-With-C-Yield.aspx

class Program 
    { 
     static void Main(string[] args) 
     { 
      Predicate<int> when = i => i > 100 && Console.ReadKey().KeyChar.ToString() == "0"; 

      foreach(var i in Numbers().BreakOn(when)) 
      { 
       Console.WriteLine(i); 
      } 

      Console.ReadLine(); 
     } 

     private static IEnumerable<int> Numbers() 
     { 
      var i = 0; 
      while(true) 
      { 
       yield return i++; 
      } 
     } 


    } 

    public static class Util 
    { 
     public static IEnumerable<int> BreakOn(this IEnumerable<int> sequence, Predicate<int> when) 
     { 
      foreach(int i in sequence) 
      { 
       if(when(i)) 
       { 
        yield break; 
       } 
       yield return i; 
      } 
     } 
} 
+0

哇,這是一個奇妙的想法。產量可以給我一些類似的語法。我喜歡這個人解釋它的方式。簡直太棒了......他稱之爲學術界的部分。但是,實際上,這將是一個循環來檢查和設置一個布爾值。感謝這個想法和文章 – Josh 2009-08-27 13:38:12

+0

我喜歡這篇文章和你的想法。但是,最終,我需要一種方式來打破循環外部函數即使我使用yield和external方法對嗎?我如何在中間打破它? – Josh 2009-08-27 13:42:41

+0

這與Take(100)類似。計數達到100時,無限循環中斷。因此,您需要爲IEnumerable定義擴展方法並使用'yield break'。 當你的破壞條件得到滿足。由於您可以將所有迭代器鏈接在一起,並且每個項目都像傳送帶上的項目一樣處理,當代碼達到收益率中斷時,循環結束。 – chandmk 2009-08-27 14:27:52