首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >等待BackgroundWorker完成吗?

等待BackgroundWorker完成吗?
EN

Stack Overflow用户
提问于 2012-05-18 09:34:36
回答 4查看 4.4K关注 0票数 1

我有两个异步进程,它们需要一个接一个地调用(一个是XML backgroundworker,另一个是使用在第一个进程中创建的XML文件的令人讨厌的BW )。这些线程的主要原因是通过进度条停止UI冻结并提供状态更新--因为这样的同步方法是不可取的/不可能的。

代码语言:javascript
运行
复制
if (!CreateXMLBW.IsBusy)
{
CreateXMLBW.RunWorkerAsync("");
}
if (!CreateRarBW.IsBusy)
{
CreateRarBW.RunWorkerAsync();
}

我不能将第二个BW放在第一个完成事件中,因为进程可以单独使用,因此,如果我只想创建XML文件,我可以这样做。

我尝试过使用AutoResetEventWaitOne,但是这个(不管是什么原因)仍然不能工作。

还有其他方法可以等待BW完成而不冻结主UI线程吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-05-18 10:25:40

您的场景正是Task所设计的。在特定情况下,您的代码可能如下所示:

代码语言:javascript
运行
复制
public delegate void UpdateUI(int progress);

private void RunOneAfterAnotherAsync()
{
    Task<XmlElement> task = Task.Factory.StartNew<XmlElement>(CreateXMLBW);
    task.ContinueWith(CreateRarBW);
}

private XmlElement CreateXMLBW()
{
    // your code

    // progress
    progressBar1.Invoke((UpdateUI)UpdateProgressBar, new object[] {progressValue});

    // result
    XmlDocument doc = new XmlDocument();
    return doc.CreateElement("element");
}

private void CreateRarBW(Task<XmlElement> task)
{
    CreateRarBW(task.Result);
}

private void CreateRarBW(XmlElement arg)
{
    // your code
}

public void UpdateProgressBar(int value)
{
    this.progressBar1.Value = value;
}

RunOneAfterAnotherAsync没有阻塞,您的两个方法一个接一个地异步运行。只有当CreateRarBW毫无例外地结束时,CreateXMLBW才会运行,但是您可以通过在ContinueWith中使用附加参数来改变这一点。

您可以做的远远超过这个示例演示-我鼓励您探索任务类。

编辑

我对这个例子做了一些扩展,将一个从第一个任务传递到第二个任务的结果合并起来。还添加了UI进度示例。

票数 1
EN

Stack Overflow用户

发布于 2012-05-18 09:39:57

如果您不想阻止UI直到等待事件(所以我想您要做一些事情),您可以在DoWork()的末尾引发一个事件,并且UI线程可以接收它。

如果您使用的是4.0,并且可以避免使用BackgroundWorker,则可以使用来自TPL的Task.ContinueWith

伪代码可能如下所示:

代码语言:javascript
运行
复制
   Action action =(() => DoWorkMethod());
   Task.Factory.StartNew(() => action()).ContinueWith(()=>CallAfterComplete());
票数 1
EN

Stack Overflow用户

发布于 2012-05-18 09:44:57

您还可以使用类似于本例中的任务

代码语言:javascript
运行
复制
class Program
{
    static XElement CreateXml()
    {
        System.Threading.Thread.Sleep(1000);
        return XElement.Parse(@"<FooBar>Hi!</FooBar>");
    }

    static void ProceedXml(XElement xml)
    {
        System.Threading.Thread.Sleep(1000);
        Console.WriteLine(xml.ToString());
    }

    public static void Main()
    {
        Task.Factory.StartNew<XElement>(CreateXml)
                    .ContinueWith(t => ProceedXml(t.Result));
        Console.ReadKey();
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10650137

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档