从Task.Factory.StartNew启动ManualResetEvent冻结我的UI

时间:2014-04-21 20:48:51

标签: c# .net winforms task-parallel-library task

请看一下这个功能:

private ManualResetEvent _manualResetEvent;

public void DoWork(decimal loops, decimal delay)
{
    _manualResetEvent = new ManualResetEvent(false);
    _tokenSource = new CancellationTokenSource();
    var token = _tokenSource.Token;
    Task.Factory.StartNew(() =>
    {
        try
        {
            Parallel.ForEach(_indexedSource,
                new ParallelOptions
                {
                    MaxDegreeOfParallelism = parallelThreads //limit number of parallel threads 
                },
                file =>
                {
                    if (token.IsCancellationRequested)
                        return;
                    //do work...
                });
        }
        catch (Exception)
        { }

    }, _tokenSource.Token,
    TaskCreationOptions.None,
    TaskScheduler.Default).ContinueWith(
            t =>
            {
                _loopCounter++;
                if (_loopCounter < loops && _shouldContinue) // Here i want to start my timer
                {
                    if (Iteration.LoopsDelay != 0)
                    {                                
                        if (StartTimerLoopDelayEventHandler != null)
                            StartTimerLoopDelayEventHandler();
                        _manualResetEvent.WaitOne((int)Iteration.LoopsDelay * 1000);
                        //do work...
                        DoWork(loops, delay);
                    }
                    else
                        //do work...
                        DoWork(loops, delay);
                }
                else
                {
                    //finish...                        
                    if (OnFinishWorkEventHandler != null)
                        OnFinishWorkEventHandler(this, EventArgs.Empty);
                }
            }
        , TaskScheduler.FromCurrentSynchronizationContext() //to ContinueWith (update UI) from UI thread
        );
}

此函数播放我的文件,并在完成后检查下一个循环之前是否有延迟,如果有延迟启动事件:

if (StartTimerLoopDelayEventHandler != null)
    StartTimerLoopDelayEventHandler();

此事件从我的主窗体启动我的计时器,但我的问题是我的UI冻结

1 个答案:

答案 0 :(得分:1)

您正在等待UI线程中的手动重置事件。这意味着你将在设置之前阻止,并且在完成之前不允许UI执行任何其他操作。这阻碍了UI;你不想那样做。你应该异步处理这个;而不是将MRE保留在Task上,以便您可以向Task添加续集。

相关问题