You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows Forms卡牌应用随机数生成引发死锁问题求助

卡牌随机分配程序问题修复

问题概述

需要实现一副牌(1-54)的随机分配:生成全部不重复随机数,7个分配给用户按钮、7个给电脑,剩余存入队列。当前程序启动后界面冻结60秒,随后抛出错误:

托管调试助手“ContextSwitchDeadlock”:“CLR 无法在60秒内从COM上下文0xa73c68切换到COM上下文0xa73bb0。”

核心错误原因

  1. 随机数生成逻辑死循环:GenerateRandomNumber方法的去重逻辑完全错误,无法生成足够数量的不重复随机数,导致循环永远无法结束,占用UI线程引发死锁。
  2. 图片路径获取方式错误:通过String.Join拼接栈元素为字符串后截取的方式,会错误获取数字的字符片段(而非完整卡牌编号),导致图片加载失败。
  3. 文件后缀不匹配:卡牌文件后缀为.jpg,但代码中使用.png,会导致图片加载异常。

修复后的完整代码

1. 窗体构造与初始化

public FmClassic()
{
    InitializeComponent();
    // 初始化卡牌分配
    InitializeCardDistribution();
}

2. 卡牌分配核心方法

private List<int> _shuffledCards;
private Queue<int> _remainingCards;
private List<int> _userCards;
private List<int> _computerCards;

private void InitializeCardDistribution()
{
    // 生成1-54的完整卡牌列表
    _shuffledCards = Enumerable.Range(1, 54).ToList();
    // 洗牌(Fisher-Yates算法,高效无重复)
    ShuffleCards(_shuffledCards);
    
    // 分配用户7张牌
    _userCards = _shuffledCards.Take(7).ToList();
    // 分配电脑7张牌
    _computerCards = _shuffledCards.Skip(7).Take(7).ToList();
    // 剩余卡牌存入队列
    _remainingCards = new Queue<int>(_shuffledCards.Skip(14));
    
    // 设置用户按钮图片
    SetUserButtonImages();
}

// Fisher-Yates洗牌算法
private void ShuffleCards(List<int> cards)
{
    Random random = new Random();
    int n = cards.Count;
    while (n > 1)
    {
        n--;
        int k = random.Next(n + 1);
        (cards[k], cards[n]) = (cards[n], cards[k]);
    }
}

3. 设置用户按钮图片

private void SetUserButtonImages()
{
    string cardPath = @"C:\filepath\"; // 确保路径正确
    button1.Image = Image.FromFile($"{cardPath}{_userCards[0]}.jpg");
    button2.Image = Image.FromFile($"{cardPath}{_userCards[1]}.jpg");
    button3.Image = Image.FromFile($"{cardPath}{_userCards[2]}.jpg");
    button4.Image = Image.FromFile($"{cardPath}{_userCards[3]}.jpg");
    button5.Image = Image.FromFile($"{cardPath}{_userCards[4]}.jpg");
    button6.Image = Image.FromFile($"{cardPath}{_userCards[5]}.jpg");
    button7.Image = Image.FromFile($"{cardPath}{_userCards[6]}.jpg");
}

关键改进点

  • 使用Fisher-Yates洗牌算法生成无重复的随机卡牌序列,避免死循环,效率更高。
  • 直接通过列表索引获取卡牌编号,避免字符串拼接截取的错误。
  • 分离卡牌分配与UI设置逻辑,代码结构更清晰。
  • 修正图片后缀为.jpg,匹配实际文件格式。

内容的提问来源于stack exchange,提问作者contingiouscrayon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 01:38:23