gpt4 book ai didi

C# 打印和线程

转载 作者:太空狗 更新时间:2023-10-29 20:02:11 25 4
gpt4 key购买 nike

我需要用户能够扫描一系列元素并为每件元素打印 x 个标签。我目前正在尝试使用后台工作人员来完成此操作,但我遇到了一个问题,即他们扫描元素的速度如此之快,并且后台工作人员阻塞的每件元素都有太多要打印的标签。这就是我为每次扫描生成后台工作线程的方式,因为在打印大量标签时会发生争用。

 private void RunPrintWorker()
{
if (printWorker.IsBusy)
{
printWorker = new BackgroundWorker();
printWorker.DoWork += new DoWorkEventHandler(printWorker_DoWork);
printWorker.RunWorkerAsync();
}
else
printWorker.RunWorkerAsync();
}

我没有从后台工作人员那里得到任何异常,它似乎没有足够快地创建线程。我是使用多线程的新手,所以任何人都可以指出我做错的方向吗?

谢谢。

编辑:感谢大家的建议和阅读 Material ,这应该很有帮助。标签的打印顺序并不重要,因为它们扫描速度非常快,而且标签也只打印到一台打印机。我会在启动并运行实现后标记答案。

编辑:Austin,下面是我如何设置打印方法。在我只是在我的 RunPrintWorker 方法中调用 LabelPrinter.PrintLabels 之前。现在我正在重做这个,我无法弄清楚要传递给 SizeQueue 方法的内容。我应该将新创建的打印文档传递给它吗?

 public class LabelPrinter
{
private int CurrentCount = 0;

private List<int> _selectedRows = new List<int>();
public List<int> SelectedRows
{
get { return _selectedRows; }
set { _selectedRows = value; }
}

private string _selectedTemplate;
public string SelectedTemplate
{
get { return _selectedTemplate; }
set { _selectedTemplate = value; }
}

private string _templateDirectory = string.Empty;
public string TemplateDirectory
{
get { return _templateDirectory; }
set { _templateDirectory = value; }
}

public void PrintLabels(PrintDocument printDoc, PageSettings pgSettings, PrinterSettings printerSettings, List<int> selectedRows, string selectedTemplate, string templateDir)
{
this._selectedRows = selectedRows;
this._selectedTemplate = selectedTemplate;
this._templateDirectory = templateDir;

printDoc.DefaultPageSettings = pgSettings;
printDoc.PrinterSettings = printerSettings;

printDoc.PrinterSettings.MaximumPage = selectedRows.Count();
printDoc.DefaultPageSettings.PrinterSettings.ToPage = selectedRows.Count();
printDoc.PrinterSettings.FromPage = 1;

printDoc.PrintPage += new PrintPageEventHandler(printDoc_PrintPage);

printDoc.Print();
}

private void printDoc_PrintPage(object sender, PrintPageEventArgs e)
{
CurrentCount = DrawLabel.DrawLabelsForPrinting(e, SelectedTemplate, SelectedRows, CurrentCount, TemplateDirectory);
}
}

最佳答案

尝试将项目添加到队列中(例如,Queue<Item>)并让 BackgroundWorker 处理队列。

编辑: 添加一些可能适合您的简单、未经测试的代码。我会用它的处理器封装打印队列,然后只向它发送作业。

class SimpleLabelPrinter
{
public bool KeepProcessing { get; set; }
public IPrinter Printer { get; set; }

public SimpleLabelPrinter(IPrinter printer)
{
Printer = printer;
}


/* For thread-safety use the SizeQueue from Marc Gravell (SO #5030228) */
SizeQueue<string> printQueue = new SizeQueue<string>();

public void AddPrintItem(string item)
{
printQueue.Enqueue(item);
}

public void ProcessQueue()
{
KeepProcessing = true;

while (KeepProcessing)
{
while (printQueue.Count > 0)
{
Printer.Print(printQueue.Dequeue());
}

Thread.CurrentThread.Join(2 * 1000); //2 secs
}
}
}

class Program
{
static void Main(string[] args)
{
SimpleLabelPrinter printer1 = new SimpleLabelPrinter(...);
SimpleLabelPrinter printer2 = new SimpleLabelPrinter(...);

Thread printer1Thread = new Thread(printer1.ProcessQueue);
Thread printer2Thread = new Thread(printer2.ProcessQueue);

//...

printer1.KeepProcessing = false; //let the thread run its course...
printer2.KeepProcessing = false; //let the thread run its course...
}
}

SizeQueue implementation

编辑 2:解决问题中的更新代码

首先,我将定义一个 PrintJob包含要打印的份数以及完整的标签文本或足够的数据来派生它的类(如数据库查询的 ID)。这将导致您替换 SizeQueue<string>在我上面的代码中为 SizeQueue<PrintJob>以及AddPrintItem(string item)AddPrintJob(PrintJob job) .

其次,我会将您的 LabelPrinter 代码分开(也许创建 IPrinter 接口(interface))并将其传递到我的 SimpleLabelPrinter 的构造函数中(此时可能不是最好的名称,但我会让您处理)。

接下来,在适合您的应用程序的任何地方创建您的 LabelPrinter 和 SimpleLabelPrinter(例如 printer1)(在您的应用程序关闭或“清理”方法中,确保将 KeepProcessing 设置为 false,以便其线程结束)。

现在,当您扫描一个项目时,您将它发送到 SimpleLabelPrinter:

printer1.AddPrintJob(new PrintJob(labelText, numberOfCopies));

关于C# 打印和线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2338153/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com