c#等待条件继续foreach循环

时间:2013-12-12 13:18:49

标签: c# c#-4.0 foreach

所以在Silverlight背后的代码中,我正在对foreach循环进行异步调用,调用方法。

问题是,我想等待,直到调用该方法,然后继续循环。

        foreach (Object itm in DataSource.DataView)
        {
            DispatcherTimer clock = new DispatcherTimer();
            clock.Interval = TimeSpan.FromSeconds(8);

            clock.Tick += (object sendC, EventArgs c) =>
            {
                clock.Stop();
            //new System.Threading.Timer(openCallBack, 0, 2000);
                open(0, itm);
                // Some code here
            };
            clock.Start();
        }

所以在这里,我正在创建一个等待8秒的计时器。就像在这个question

中一样

问题是,循环继续,即使我没有进入Tick事件。

结果是,在我的tick事件中,我将使用最后一个同一个对象进行3次。这真的很不稳定。

所以,我想等待继续前进,直到我通过Tick

            bool continue = false;
            foreach (Object itm in DataSource.DataView)
            {
                DispatcherTimer clock = new DispatcherTimer();
                clock.Interval = TimeSpan.FromSeconds(8);

                clock.Tick += (object sendC, EventArgs c) =>
                {
                    clock.Stop();
                //new System.Threading.Timer(openCallBack, 0, 2000);
                    open(0, itm);
                    continue = true;
                    // Some code here
                };
                clock.Start();

             //continue loop if continue is true
            }

所以,open方法实际上是每8秒调用一次。

我该怎么做?

1 个答案:

答案 0 :(得分:1)

是的,你正在尝试做一些Silverlight被明确设计为不允许你做的事情(执行同步长时间运行的活动)。

我建议你重构一下:创建一个传递你的IEnumerable的类,它创建一个DispatchTimer,并有一个启动方法,你可以连接回调并启动计时器。然后在每个Tick回调中,使用MoveNext移动到下一个项目(如果没有下一个项目则终止)并调用Open方法。 (我还建议使用Cancel方法,以便终止处理,出现某种状态事件等。)

...
var myProcessor = new SerialProcessor(((IEnumerable)DataSource.DataView).GetEnumerator())
myProcessor.Start();
...

public class SerialProcessor
{
    private IEnumerator items;
    private DispatcherTimer clock;

    public SerialProcessor(IEnumerable items)
    {
        this.items = items;
        this.clock = new DispatcherTimer();
        clock.Interval = TimeSpan.FromSeconds(8);

        clock.Tick += (o, e) =>
        {
            clock.Stop();
            if (!this.items.MoveNext()) return;
            var item = this.items.Current;
            open(0, item); // <-- This is where you do whatever processing you want to do. If you want to be REALLY slick, pass it into this class as a Func<> or Action<>
            // Resume processing
            clock.Start();
        };
    }

    public void Start()
    {
        clock.Start();
    }

    // Add Cancel method to stop the clock, status events, etc.
}