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

C# PrintDocument打印图像正常后停止,程序偶发冻结求助

解决C# PrintDocument组件图像打印异常与程序冻结问题

问题根源分析

从提供的代码和现象来看,核心问题集中在资源泄漏、逻辑错误和UI线程阻塞三个方面:

  1. 图像资源未释放:在PrintPage事件的循环中反复调用Image.FromFile加载同一图像,却未释放资源,导致内存持续占用,最终引发程序冻结。
  2. 矩形索引未更新:循环中currentRectangle没有随循环迭代递增,导致所有图像都绘制在同一位置,看起来像是"停止打印图像"。
  3. 同步打印阻塞UI:pd.Print()是同步方法,会阻塞UI线程,多次执行后容易导致程序无响应。

具体修复方案

1. 修复图像资源泄漏

将图像加载移到循环外,使用using语句确保资源自动释放:

private void printLabelBack_PrintPage(object sender, PrintPageEventArgs e)
{
    // 一次性加载图像,using块确保使用后自动释放
    using (Image imageRecipe6 = Image.FromFile(@"C:\Users\Owner\source\repos\PackLabels\PackLabels\Images\logoImage32.jpg"))
    {
        for (int xy = 0; xy < 8; xy++)
        {
            currentRectangle = xy + 1; // 同步更新矩形索引
            changeRectangleLabel();
            
            addressYCoordinate = rectangleY;
            addressXCoordinate = rectangleX + 25f;
            
            e.Graphics.DrawImage(imageRecipe6, addressXCoordinate, addressYCoordinate, imageWidth, imageHeight);
        }
    }
}

2. 修正矩形位置逻辑

更新changeRectangleLabel方法,用switch替代冗余的if判断,提升代码可读性和效率:

public void changeRectangleLabel()
{
    switch(currentRectangle)
    {
        case 1:
            rectangleX = 35f;
            rectangleY = 10f;
            break;
        case 2:
            rectangleX = 302f;
            rectangleY = 10f;
            break;
        case 3:
            rectangleX = 569f;
            rectangleY = 10f;
            break;
        case 4:
            rectangleX = 836f;
            rectangleY = 10f;
            break;
        case 5:
            rectangleX = 35f;
            rectangleY = 402f;
            break;
        case 6:
            rectangleX = 302f;
            rectangleY = 402f;
            break;
        case 7:
            rectangleX = 567f;
            rectangleY = 402f;
            break;
        case 8:
            rectangleX = 836f;
            rectangleY = 402f;
            break;
    }
}

3. 异步打印避免UI阻塞

将同步打印改为异步执行,防止UI线程被长时间阻塞:

private async void buttonBack_Click(object sender, EventArgs e)
{
    GetRecipeInfo();
   
    using (PrintDocument pd = new PrintDocument())
    {
        pd.DefaultPageSettings.PrinterSettings.Duplex = System.Drawing.Printing.Duplex.Simplex;
        pd.DefaultPageSettings.Landscape = true;
        pd.PrintPage += printLabelBack_PrintPage;
        
        // 用Task.Run将打印操作移到后台线程
        await Task.Run(() => pd.Print());
    }
}

额外排查建议

  • 清理打印机队列:删除打印机中堆积的未完成任务,避免队列阻塞导致打印异常。
  • 检查内存使用:使用Visual Studio诊断工具(Debug -> Performance Profiler)监控内存,确认资源是否被正确释放。
  • 更新打印机驱动:老旧驱动可能存在兼容性问题,更新到最新版本可解决部分打印异常。
  • 测试小尺寸图像:用小分辨率图像测试,验证内存泄漏是否是冻结的核心原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 01:28:17