代码之家  ›  专栏  ›  技术社区  ›  Dan Kendall

无阻塞顺序异步任务

  •  4
  • Dan Kendall  · 技术社区  · 15 年前

    有没有一种标准的方法来实现这一点,或“最佳实践”?

    BackgroundWorker 我立刻感到快乐和轻微的恐惧。启动整个程序的代码让人感觉特别不舒服。我觉得一定有更好的办法,或者至少有一个既定的办法。

    非常感谢你的建议。


    protected void runAsyncTask(SequentialTask seqTask)
        {
            if (HasErrored) return;
    
            DoWorkEventHandler worker = (s, e) =>
            {
                setTaskStartStatusMessage(seqTask.TaskMessage);
                ShowProgress = true;
                seqTask.Task((BackgroundWorker)s);
            };
    
            ProgressChangedEventHandler progress = (s, e) =>
            {
                if (seqTask.TaskProgress != null)
                    seqTask.TaskProgress(e.ProgressPercentage, e.UserState);
            };
    
            RunWorkerCompletedEventHandler done = null;
            done = (s, e) =>
            {
                ShowProgress = false;
                if (e.Error != null)
                {
                    HasErrored = true;
                    displayTaskExceptionMessage(e.Error, seqTask.TaskMessage);
                }
                else
                {
                    setTaskCompleteStatusMessage(seqTask.TaskMessage);
                    if (seqTask.TaskComplete != null)
                        seqTask.TaskComplete();
                }
                ((BackgroundWorker)s).RunWorkerCompleted -= done;
                ((BackgroundWorker)s).DoWork -= worker;
                ((BackgroundWorker)s).ProgressChanged -= progress;
    
                if (seqTask.NextTask != null && (seqTask.CanExecuteNext == null ? true : seqTask.CanExecuteNext()))
                    runAsyncTask(seqTask.NextTask);
            };
    
            if (seqTask.TaskProgress != null)
                backgroundWorker.WorkerReportsProgress = true;
            backgroundWorker.DoWork += worker;
            backgroundWorker.RunWorkerCompleted += done;
            backgroundWorker.ProgressChanged += progress;
            backgroundWorker.RunWorkerAsync();
        }
    

    SequentialTask 只是一组简单的属性:

    public class SequentialTask
    {
        public Action<BackgroundWorker> Task { get; set; }
        public String TaskMessage { get; set; }
        public Func<bool> CanExecuteNext { get; set; }
        public Action<int, object> TaskProgress { get; set; }
        public Action TaskComplete { get; set; }
        public SequentialTask NextTask { get; set; }
    }
    

    这导致了类似Perl的语法:

    runAsyncTask(new SequentialTask()
            {
                Task = (x) => loadFile(),
                TaskMessage = "Load File",
                CanExecuteNext = null,
                NextTask = new SequentialTask()
                {
                    Task = (x) => validateImport(),
                    TaskMessage = "Validate Input Lines",
                    TaskComplete = () =>
                    {
                        if (!ImportIsValid)
                            displayValidationMessages();
                    },
                    CanExecuteNext = () => ImportIsValid,
                    NextTask = new SequentialTask()
                    {
    

    2 回复  |  直到 15 年前
        1
  •  7
  •   Adam Barney    15 年前

    你看过.NET 4.0中的任务并行库(TPL)吗?这允许您执行以下操作:

    Task firstTask = new Task(()=>RunStepOne());
    firstTask.ContinueWith(task=>()=>RunSecondStep());
    firstTask.Start();
    

    在TPL上有很多创建、继续和停止任务的选项。当然值得一看。

        2
  •  0
  •   CodingGorilla    15 年前

    我看你的方法没有什么问题。最重要的是:它起作用了。