【问题标题】:Semaphore for control downloadinf process控制 downloadinf 进程的信号量
【发布时间】:2014-01-21 12:26:32
【问题描述】:

我在这段代码中使用了信号量

static Semaphore s = new Semaphore(1,1);
private void button2_Click(object sender, EventArgs e)
        {

                 Thread[] t = new Thread[full_list];
                 for(int i=0;i<full_list;i++)
                 {    
                     if (sorted_list[i].audio_node != null)
                         if (sorted_list[i].audio_node.Checked == true)
                         {
                             t[i] = new Thread(DownloadFile);
                             t[i].Start(sorted_list[i]);
                         }
                  }

           }

private  void DownloadFile(object a)
        {
            s.WaitOne();
            if (InvokeRequired)
            {
                BeginInvoke(new DownloadFileDelegate(DownloadFile),new object[1] {a} );
                return;
            }
            else
            {
                download process....

                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                }
            }
            s.Release();
        }

但它不起作用,我的程序冻结了。我正在尝试解决这个问题,但我不知道为什么它不适用于 Semaphore。所有组件包括下载工作正常。

【问题讨论】:

    标签: c# download synchronization semaphore


    【解决方案1】:

    您在非 gui 线程上运行 DownloadFile。在获取信号量的方法中,然后调用InvokeRequired。它将返回true,因为你不在gui线程上,所以你调用DownloadFile on the gui thread. You then return without releasing the semaphore, so whenDownloadFile`在gui线程上运行它会尝试做的第一件事是获取信号量,因为它不能它会阻塞。

    在您的代码中创建一个线程来安排对 gui 线程的回调没有多大意义。你真正需要做的是在非 gui 线程上下载文件,然后当你得到它时,调用 gui 线程来处理你下载的内容。

    关于信号量,您应该将代码包装在 try\finally 块中,以确保它始终被释放,即使您在代码中间有返回:

    s.WaitOne();
    try
    {
      // Rest of method
    }
    finally
    {
      s.Release();
    }
    

    【讨论】:

    • 关于下载,我想在下载时在 Gui 中显示进度。
    • @jenius - 当你在一个线程上下载时,你可以在 gui 线程上调用 BeginInvoke 一个方法来说明已经下载了多少,相应地更新 gui。
    • 我这样做了,现在信号量不会冻结我的程序,但它仍然允许同时下载 2 个或更多文件。这对我来说是不可接受的。
    • @jenius - 你不需要信号量。只需在开始下载时设置bool,并在下载完成后将其设置为 false。然后,您可以在再次尝试下载时检查您是否已经在下载。或者,在下载完成之前禁用开始下载的按钮,这样用户将无法开始多次下载。
    • 谢谢。这很有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 2019-06-19
    • 2020-12-23
    • 2016-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多