Остановить цикл внутри метода в C # - PullRequest
2 голосов
/ 27 августа 2009

Есть ли способ остановить работающий цикл внутри другого метода или динамически вставить оператор break в C #?

Спасибо

Edit: я хочу иметь возможность динамически перехватить метод и вставить разрыв, чтобы остановить цикл, когда событие запускается в другой функции. У меня есть несколько экземпляров класса, и я хочу останавливать цикл в каждом экземпляре всякий раз, когда требуется и управлять всеми экземплярами. Рассмотрим несколько экземпляров в общем списке

Пример:

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.

Ответы [ 6 ]

7 голосов
/ 27 августа 2009

Если все это работает в одном потоке, это не имеет никакого смысла. Если цикл работает, то больше ничего не выполняется одновременно. Если вы запускаете цикл в другом потоке, а метод управления - в другом потоке, вы можете либо полностью прервать поток цикла, либо проверить флаг внутри цикла, чтобы решить, следует ли вам разорвать и установить флаг соответствующим образом в методе управления .

Обновление: заставить эту функцию возвращать логическое значение, указывающее, следует ли разбивать и использовать его в выражении "if":

if (myFunctionShouldBreakLoop()) break;
3 голосов
/ 27 августа 2009

Другой вариант - вызывать 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;
   }
}

Таким образом, вы можете управлять циклом извне ....

2 голосов
/ 27 августа 2009

Как насчет использования итераторов и получения магии для решения проблемы.

Вот статья о бесконечных списках, которые могут быть полезны

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;
            }
        }
}
2 голосов
/ 27 августа 2009

Имейте условие в заблокированном свойстве.

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;
}
1 голос
/ 27 августа 2009

Краткий ответ: нет. Если вы не контролируете код, то вы не можете заставить цикл завершиться.

Если вы действительно контролируете код, вы можете наладить какое-то сотрудничество, но это звучит грязно. Может быть, вы можете объяснить, почему?

1 голос
/ 27 августа 2009

Я думаю, вы можете использовать флаг

bool stop = false;

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