1

尝试使用 XSL 转换 XML 文件并打印输出。但是,收到以下消息:调用线程无法访问此对象,因为不同的线程拥有它。

要设置检查文件的时间间隔,请在 OnStart 中添加一个计时器。

            if (findPrinter() > 0)
            {
                System.Timers.Timer printNetterCheck = new System.Timers.Timer();
                printNetterCheck.Elapsed += new ElapsedEventHandler(OnTimedEvent);

                printNetterCheck.Interval = 30000;
                printNetterCheck.Enabled = true;
            }

OnTimedEvent:

    private void OnTimedEvent(object source, ElapsedEventArgs e)
    {            
        getFiles();
    }

如果有可用的文件,请调用 print:

            foreach (string file in files)
            {
                try
                {
                    StringWriter xslTransformResult = new StringWriter();
                    XslCompiledTransform xslt = new XslCompiledTransform();
                    xslt.Load(xslPath);
                    xslt.Transform(file, null, xslTransformResult);

                    if (print(xslTransformResult) == 1)
                    {
                              //do some things

打印功能:

    private int print(StringWriter transformedXML)
    {
        //assume OK
        int rc = 1;

        try
        {
            StringReader printNetterStreamReader = new StringReader(transformedXML.ToString());
            PrintSystemJobInfo printNetterJob = printer.AddJob("PrintNetterPrint");

            Stream printNetterStream = printNetterJob.JobStream;


            Byte[] printNetterByteBuffer = UnicodeEncoding.Unicode.GetBytes(printNetterStreamReader.ReadToEnd());

            printNetterStream.Write(printNetterByteBuffer, 0, printNetterByteBuffer.Length);
            printNetterStream.Close();
        }
        catch (Exception e)
        {
            //return fail
            rc = -1;
            eventLog.WriteEntry("Error printing: " + e.Message, EventLogEntryType.Error);
        }

        return rc;

    }

调用 print 时,我收到线程错误。找到了一些关于 Dispatchers 等的东西。但是这些在使用服务时不可用。

4

2 回答 2

1

检查PrintQueue.AddJob

该方法进行 COM 调用,要求应用程序在单个单元 ( STA) 中运行。解决此问题的最简单方法是添加STAThreadAttributeMain强制应用程序在单个线程中运行的内容。如果您需要在应用程序中使用多线程,那么您将需要实现必要的管道以PrintQueueSTA Thread.

// Create a factory to hold your printer configuration
// So that it can be retrieved on demand
// You might need to move the findPrinter() logic
public class PrintQueueFactory
{
    private static PrintQueue _instance = new PrinterQueue(/* Details */);

    public static PrintQueue PrintQueue { get { return _instance; } }
}

private int print(StringWriter transformedXML)
{
    //assume OK
    int rc = 1;

    try
    {
        var printer = PrintQueueFactory.PrintQueue;
        var staThread = new Thread(() => Print(printer, transformedXML.ToString()));
        staThread.SetApartmentState(ApartmentState.STA);
        staThread.Start();
        staThread.Join();
    }
    catch (Exception e)
    {
        //return fail
        rc = -1;
        eventLog.WriteEntry("Error printing: " + e.Message, EventLogEntryType.Error);
    }

    return rc;

}

private static void Print(PrintQueue printer, string lines)
{
    using(var printNetterJob = printer.AddJob("PrintNetterPrint"))
    using(var printNetterStreamReader = new StringReader(lines))
    using(var printNetterStream = printNetterJob.JobStream)
    {
        Byte[] printNetterByteBuffer = UnicodeEncoding.Unicode.GetBytes(printNetterStreamReader.ReadToEnd());
        printNetterStream.Write(printNetterByteBuffer, 0, printNetterByteBuffer.Length);
    }
}
于 2013-04-22T12:44:48.487 回答
0

也许,当您使用 Timer 控件时,它与多线程有关,也许您应该检查 Timer.Elapsed 事件处理程序中是否需要调用 (InvokeRequired)。

如果是这样,您应该创建一个委托来调用此函数,以便它可以在正确的线程中执行。

检查这个需要调用的问题

于 2013-04-22T11:46:17.287 回答