Skip to main content
 首页 » 编程设计

c#之多任务调度导致死锁

2024年02月06日30fff_TT

该应用程序用于电话服务。所有调用都放入队列中。由于端口限制,每次应用最多只能接4个调用。

在下面的代码中,我当然将最大信号量设置为4。

然而在这个小小的模拟程序中,却陷入了僵局。任务都没有完成。

class Program 
{ 
    static readonly Queue<string> phoneNumbers = new Queue<string>(); 
    static Semaphore semaphore; 
    static void Main(string[] args) 
    { 
        string[] dialCollection = new string[9]; 
        dialCollection[0] = "test 00000000000"; 
        dialCollection[1] = "test 11111111111"; 
        dialCollection[2] = "test 22222222222"; 
        dialCollection[3] = "test 33333333333"; 
        dialCollection[4] = "test 44444444444";  
        dialCollection[5] = "test 55555555555"; 
        dialCollection[6] = "test 66666666666"; 
        dialCollection[7] = "test 77777777777"; 
        dialCollection[8] = "test 88888888888"; 
        foreach (var item in dialCollection) 
        { 
            phoneNumbers.Enqueue(item); 
        } 
        semaphore = new Semaphore(0, 4); 
        Console.WriteLine("Begin"); 
        List<Task> tasks = new List<Task>(); 
        do 
        { 
            string phoneNumber = phoneNumbers.Dequeue(); 
            try 
            { 
                tasks.Add(Task.Factory.StartNew(() => { MakeCall(phoneNumber); })); 
            } 
            catch (Exception) 
            { 
                //put the number back in the queue if the MakeCall method throws an exception... 
                phoneNumbers.Enqueue(phoneNumber); 
            } 
        } 
        while (phoneNumbers.Count > 0); 
        Task.WaitAll(tasks.ToArray()); 
        Console.WriteLine("End");  //code not reach this break point. 
        Console.Read(); 
    } 
 
    private static void MakeCall(string phoneNumber) 
    { 
        semaphore.WaitOne(); 
        Console.WriteLine(phoneNumber); 
        semaphore.Release(); 
    } 
} 

请您参考如下方法:

您的信号量初始计数设置为 0,因此没有可用信号量。你有两个选择,用所有四个可用的来构造它:

semaphore = new Semaphore(4, 4); 

或者在开始 WaitAll

之前释放 4
semaphore.Release(4);