【问题标题】:c# 2 BackgroundWorkers started simultaneouslyc#2个BackgroundWorkers同时启动
【发布时间】:2013-08-19 19:18:55
【问题描述】:

有人可以看看并告诉我我的代码有什么问题吗? 我正在“即时”创建 2 个 BackgroundWorkers 并尝试同时启动它们。 类 Listen 和 Scan 背后的代码在单独执行时运行良好,但是当尝试以下述方式执行它们时,由于某种原因,它们总是一个接一个地启动。

private void btn_Start_BACKWorkers_Click(object sender, RoutedEventArgs e)
{
    string one = tbx_id1.Text;
    string second = tbx_id2.Text;
    string Status = "";
    var bw1 = new BackgroundWorker();

    bw1.DoWork += delegate
    {
        string SelectedNumber = "0"; 
        Listen myListen = new Listen(SelectedNumber );
        TOTALlist = myListen.Main();
        lbox_TOTAL.ItemsSource = addIPlist;        
    };

    var bw2 = new BackgroundWorker();
    bw2.DoWork += delegate
    {
        Send newScan = new Send(one , second);
        string Status = newScan.hey();
        FinalStatus = Status;

        lbl_SendStatus.Content = FinalStatus ;
    };

    bw1.RunWorkerAsync();
    bw2.RunWorkerAsync();
}

【问题讨论】:

  • bw2 声明在哪里?
  • 他们会做吗?您的第二个后台工作人员在第一个工作人员之后启动?
  • 对不起,我忘了显示 bw2 的声明位置,是的,bw2 似乎在 bw1 完成后开始。
  • 可能是因为 bw1 即将完成,所以当 bw2 被调用时,它似乎是连续的?例如,如果您在 bw1 委托中添加 Thread.Sleep(10000),那么 bw2 是否还在等待 bw1 开始之前?
  • “同时” 在多线程时不是一个可获取的概念。

标签: c# multithreading backgroundworker


【解决方案1】:

谢谢FerretallicA! 我无法将您的评论标记为最佳答案,所以我在这里写: 这正是解决问题的原因,BackgroundWorker bw2 对于 bw1 来说太快了,所以我添加了睡眠时间:

        bw1.RunWorkerAsync();
        System.Threading.Thread.Sleep(1000);
        bw2.RunWorkerAsync();

现在 bw1 有足够的时间启动,在 bw2 启动之前,一切正常! 谢谢大家!你太棒了! 简单的解决方案是最好的!

【讨论】:

  • 您是否尝试同步这些线程?为了线程同步的目的而将Thread.Sleep 留在原处是一个非常糟糕的主意(tm)。 FerretallicA 建议仅将其添加为快速诊断,但它不应出现在任何最终代码中。如果这些是独立的操作,那么它们以什么顺序开始/结束都无关紧要。
  • 那行不通。您需要在bw1 代码中添加睡眠inside,而不是在RunWorkerAsync 调用之间。
  • 基于这个“答案”,我只能说讨论几乎没有用。请在 DoWork 方法的开头和结尾插入日志代码,以便打印出开始/结束的时间。然后,您将更好地查看引擎盖下的线程是否按您的意愿工作。
【解决方案2】:

您可以在等待信号的线程中使用CountdownEvent

【讨论】:

    【解决方案3】:

    我没有发现任何迹象表明您的代码无法按预期工作。可能是因为 bw1 即将完成,所以当 bw2 被称为 似乎 是连续的?例如,如果在 bw1 委托中添加 Thread.Sleep(10000),那么 bw2 是否仍然等待 bw1 才能启动?

    例如:

    bw1.DoWork += delegate { 
        Console.WriteLine("Worker 1 started"); 
        Thread.Sleep(10000);
        Console.WriteLine("Worker 1 finished");
    };
    
    bw2.DoWork += delegate {
        Console.WriteLine("Worker 2 started"); 
        Console.WriteLine("Worker 2 finished"); 
    };
    
    bw1.RunWorkerAsync();
    bw2.RunWorkerAsync();
    

    应该产生:

    工人 1 已启动

    工人 2 已启动

    工人 2 完成

    工人 1 完成

    【讨论】:

    • 这是一个非常糟糕的解决方案。我可以将其理解为一种快速而肮脏的诊断,以确认这是否是问题所在,但 Thread.Sleep 不应用于同步。
    • 问题不是要solution,而是要问“有人可以看看并告诉我我的代码有什么问题吗?”。我的回答是作为确认正在发生的事情的一种方式 - 不需要solution,唯一的问题是误解观察到的行为。
    • 我理解你的意思(看看我的其他评论),但原发帖人清楚地将其视为solution,而不是你如何解释它——阅读他回答的最后一行:他补充说@ 987654327@ 为第二个线程的启动计时。未来的其他(没有经验的)读者也会这样解读。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-18
    • 2020-03-09
    相关资源
    最近更新 更多