信号量用于控制下载过程

时间:2014-01-21 12:26:32

标签: c# download synchronization semaphore

我在这段代码中使用Semaphore

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();
        }

但它不起作用,我的prorgram冻结了。我正在尝试解决这个问题,但我不知道它为何与Semaphore不兼容。所有组件都包括正确下载工作。

1 个答案:

答案 0 :(得分:1)

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

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

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

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