Freigeben über


Wie man herausfindet, ob ein Druckauftrag zu dieser Tageszeit gedruckt werden kann

Druckwarteschlangen sind nicht immer für 24 Stunden am Tag verfügbar. Sie verfügen über Start- und Endzeiteigenschaften, die festgelegt werden können, um sie zu bestimmten Tageszeiten nicht verfügbar zu machen. Diese Funktion kann z. B. verwendet werden, um einen Drucker für die ausschließliche Nutzung einer bestimmten Abteilung nach 15:00 Uhr zu reservieren. Diese Abteilung hätte eine andere Warteschlange für die Verwaltung des Druckers als andere Abteilungen. Die Warteschlange für die anderen Abteilungen wäre nach 15:00 Uhr nicht verfügbar, während die Warteschlange für die bevorzugte Abteilung jederzeit verfügbar sein könnte.

Darüber hinaus können Druckaufträge selbst so festgelegt werden, dass sie nur innerhalb einer bestimmten Zeitspanne gedruckt werden können.

Die PrintQueue und PrintSystemJobInfo Klassen, die in den APIs von Microsoft .NET Framework bereitgestellt werden, bieten eine Möglichkeit, aus der Ferne zu überprüfen, ob ein bestimmter Druckauftrag zur aktuellen Zeit in einer bestimmten Warteschlange drucken kann.

Beispiel

Das folgende Beispiel ist ein Beispiel, das Probleme mit einem Druckauftrag diagnostizieren kann.

Es gibt zwei wichtige Schritte für diese Art von Funktion wie folgt.

  1. Lesen Sie die Eigenschaften von StartTimeOfDay und UntilTimeOfDay des PrintQueue, um zu bestimmen, ob sich die aktuelle Zeit zwischen ihnen befindet.

  2. Lesen Sie die Eigenschaften von StartTimeOfDay und UntilTimeOfDay des PrintSystemJobInfo, um zu bestimmen, ob sich die aktuelle Zeit zwischen ihnen befindet.

Aber Komplikationen ergeben sich aus der Tatsache, dass diese Eigenschaften keine DateTime Objekte sind. Stattdessen sind es Int32 Objekte, die die Tageszeit als Anzahl der Minuten seit Mitternacht ausdrücken. Darüber hinaus ist dies nicht Mitternacht in der aktuellen Zeitzone, sondern Mitternacht UTC (Koordinierte Weltzeit).

Im ersten Codebeispiel wird die statische Methode ReportQueueAndJobAvailability vorgestellt, der ein PrintSystemJobInfo übergeben wird und die Hilfsmethoden aufruft, um zu bestimmen, ob der Auftrag zur aktuellen Zeit gedruckt werden kann und, wenn nicht, wann er gedruckt werden kann. Beachten Sie, dass eine PrintQueue an die Methode nicht übergeben wird. Dies liegt daran, dass die PrintSystemJobInfo einen Verweis auf die Warteschlange in ihrer HostingPrintQueue Eigenschaft enthält.

Die untergeordneten Methoden enthalten die überladene ReportAvailabilityAtThisTime-Methode , die entweder einen PrintQueue oder einen PrintSystemJobInfo als Parameter verwenden kann. Es gibt auch einen TimeConverter.ConvertToLocalHumanReadableTime. Alle diese Methoden werden weiter unten erläutert.

Die ReportQueueAndJobAvailability-Methode beginnt mit der Überprüfung, ob die Warteschlange oder der Druckauftrag zu diesem Zeitpunkt nicht verfügbar ist. Wenn eine der Beiden nicht verfügbar ist, wird überprüft, ob die Warteschlange nicht verfügbar ist. Wenn sie nicht verfügbar ist, meldet die Methode diese Tatsache und den Zeitpunkt, zu dem die Warteschlange wieder verfügbar wird. Anschließend überprüft er den Druckauftrag und meldet, wenn er nicht verfügbar ist, den nächsten Zeitraum, wann er gedruckt werden kann. Schließlich meldet die Methode den frühesten Zeitpunkt, zu dem der Auftrag gedruckt werden kann. Dies ist die spätere der folgenden zwei Zeiten.

  • Der Zeitpunkt, zu dem die Druckwarteschlange nächstes Mal verfügbar ist.

  • Der Zeitpunkt, zu dem der Druckauftrag als nächstes verfügbar ist.

Bei der Angabe von Uhrzeiten wird die ToShortTimeString Methode aufgerufen, da diese Methode die Jahre, Monate und Tage aus der Ausgabe weglässt. Sie können die Verfügbarkeit einer Druckwarteschlange oder eines Druckauftrags nicht auf bestimmte Jahre, Monate oder Tage beschränken.

static void ReportQueueAndJobAvailability (PrintSystemJobInfo^ theJob) 
{
   if (!(ReportAvailabilityAtThisTime(theJob->HostingPrintQueue) && ReportAvailabilityAtThisTime(theJob)))
   {
      if (!ReportAvailabilityAtThisTime(theJob->HostingPrintQueue))
      {
         Console::WriteLine("\nThat queue is not available at this time of day." + "\nJobs in the queue will start printing again at {0}", TimeConverter::ConvertToLocalHumanReadableTime(theJob->HostingPrintQueue->StartTimeOfDay).ToShortTimeString());
         // TimeConverter class is defined in the complete sample
      }
      if (!ReportAvailabilityAtThisTime(theJob))
      {
         Console::WriteLine("\nThat job is set to print only between {0} and {1}", TimeConverter::ConvertToLocalHumanReadableTime(theJob->StartTimeOfDay).ToShortTimeString(), TimeConverter::ConvertToLocalHumanReadableTime(theJob->UntilTimeOfDay).ToShortTimeString());
      }
      Console::WriteLine("\nThe job will begin printing as soon as it reaches the top of the queue after:");
      if (theJob->StartTimeOfDay > theJob->HostingPrintQueue->StartTimeOfDay)
      {
         Console::WriteLine(TimeConverter::ConvertToLocalHumanReadableTime(theJob->StartTimeOfDay).ToShortTimeString());
      } else
      {
         Console::WriteLine(TimeConverter::ConvertToLocalHumanReadableTime(theJob->HostingPrintQueue->StartTimeOfDay).ToShortTimeString());
      }

   }
};
internal static void ReportQueueAndJobAvailability(PrintSystemJobInfo theJob)
{
    if (!(ReportAvailabilityAtThisTime(theJob.HostingPrintQueue) && ReportAvailabilityAtThisTime(theJob)))
    {
        if (!ReportAvailabilityAtThisTime(theJob.HostingPrintQueue))
        {
            Console.WriteLine("\nThat queue is not available at this time of day." +
                "\nJobs in the queue will start printing again at {0}",
                 TimeConverter.ConvertToLocalHumanReadableTime(theJob.HostingPrintQueue.StartTimeOfDay).ToShortTimeString());
            // TimeConverter class is defined in the complete sample
        }

        if (!ReportAvailabilityAtThisTime(theJob))
        {
            Console.WriteLine("\nThat job is set to print only between {0} and {1}",
                TimeConverter.ConvertToLocalHumanReadableTime(theJob.StartTimeOfDay).ToShortTimeString(),
                TimeConverter.ConvertToLocalHumanReadableTime(theJob.UntilTimeOfDay).ToShortTimeString());
        }
        Console.WriteLine("\nThe job will begin printing as soon as it reaches the top of the queue after:");
        if (theJob.StartTimeOfDay > theJob.HostingPrintQueue.StartTimeOfDay)
        {
            Console.WriteLine(TimeConverter.ConvertToLocalHumanReadableTime(theJob.StartTimeOfDay).ToShortTimeString());
        }
        else
        {
            Console.WriteLine(TimeConverter.ConvertToLocalHumanReadableTime(theJob.HostingPrintQueue.StartTimeOfDay).ToShortTimeString());
        }
    }//end if at least one is not available
}//end ReportQueueAndJobAvailability
Friend Shared Sub ReportQueueAndJobAvailability(ByVal theJob As PrintSystemJobInfo)
    If Not(ReportAvailabilityAtThisTime(theJob.HostingPrintQueue) AndAlso ReportAvailabilityAtThisTime(theJob)) Then
        If Not ReportAvailabilityAtThisTime(theJob.HostingPrintQueue) Then
            Console.WriteLine(vbLf & "That queue is not available at this time of day." & vbLf & "Jobs in the queue will start printing again at {0}", TimeConverter.ConvertToLocalHumanReadableTime(theJob.HostingPrintQueue.StartTimeOfDay).ToShortTimeString())
            ' TimeConverter class is defined in the complete sample
        End If

        If Not ReportAvailabilityAtThisTime(theJob) Then
            Console.WriteLine(vbLf & "That job is set to print only between {0} and {1}", TimeConverter.ConvertToLocalHumanReadableTime(theJob.StartTimeOfDay).ToShortTimeString(), TimeConverter.ConvertToLocalHumanReadableTime(theJob.UntilTimeOfDay).ToShortTimeString())
        End If
        Console.WriteLine(vbLf & "The job will begin printing as soon as it reaches the top of the queue after:")
        If theJob.StartTimeOfDay > theJob.HostingPrintQueue.StartTimeOfDay Then
            Console.WriteLine(TimeConverter.ConvertToLocalHumanReadableTime(theJob.StartTimeOfDay).ToShortTimeString())
        Else
            Console.WriteLine(TimeConverter.ConvertToLocalHumanReadableTime(theJob.HostingPrintQueue.StartTimeOfDay).ToShortTimeString())
        End If

    End If 'end if at least one is not available

End Sub

Die beiden Überladungen der ReportAvailabilityAtThisTime-Methode sind identisch, mit Ausnahme des an sie übergebenen Typs, sodass unten nur die PrintQueue Version dargestellt wird.

Hinweis

Die Tatsache, dass die Methoden identisch sind, mit Ausnahme des Typs, stellt die Frage, warum das Beispiel keine generische Methode ReportAvailabilityAtThisTime<T> erstellt. Der Grund dafür ist, dass eine solche Methode auf eine Klasse beschränkt werden muss, die über die Eigenschaften StartTimeOfDay und UntilTimeOfDay verfügt, die von der Methode aufgerufen werden, aber eine generische Methode kann nur auf eine einzelne Klasse und die einzige Klasse beschränkt werden, die sowohl als auch PrintQueuePrintSystemJobInfo in der Vererbungsstruktur gemeinsam ist, die PrintSystemObject keine solchen Eigenschaften aufweist.

Die ReportAvailabilityAtThisTime-Methode (im folgenden Codebeispiel dargestellt) beginnt mit der Initialisierung einer Boolean Sentinelvariablen auf true. Sie wird zurückgesetzt auf false, wenn die Warteschlange nicht verfügbar ist.

Als Nächstes überprüft die Methode, ob die Start- und "bis"-Uhrzeit identisch sind. Wenn sie es sind, ist die Warteschlange immer verfügbar, sodass die Methode true zurückgibt.

Wenn die Warteschlange nicht immer verfügbar ist, verwendet die Methode die statische UtcNow Eigenschaft, um die aktuelle Uhrzeit als DateTime Objekt abzurufen. (Wir benötigen keine Ortszeit, da die Eigenschaften StartTimeOfDay und UntilTimeOfDay selbst in UTC-Zeit vorliegen.)

Diese beiden Eigenschaften sind jedoch keine DateTime Objekte. Sie geben Int32die Uhrzeit als die Anzahl der Minuten nach UTC-Mitternacht an. Daher müssen wir unser DateTime Objekt in Minuten nach Mitternacht konvertieren. Wenn dies abgeschlossen ist, überprüft die Methode einfach, ob "jetzt" zwischen dem Start- und dem "Bis"-Zeitpunkt der Warteschlange liegt, legt den Sentinel auf "false" fest, wenn "jetzt" nicht zwischen den beiden Zeiten liegt, und gibt den Sentinel zurück.

static Boolean ReportAvailabilityAtThisTime (PrintQueue^ pq) 
{
   Boolean available = true;
   if (pq->StartTimeOfDay != pq->UntilTimeOfDay)
   {
      DateTime utcNow = DateTime::UtcNow;
      Int32 utcNowAsMinutesAfterMidnight = (utcNow.TimeOfDay.Hours * 60) + utcNow.TimeOfDay.Minutes;

      // If now is not within the range of available times . . .
      if (!((pq->StartTimeOfDay < utcNowAsMinutesAfterMidnight) && (utcNowAsMinutesAfterMidnight < pq->UntilTimeOfDay)))
      {
         available = false;
      }
   }
   return available;
};
private static Boolean ReportAvailabilityAtThisTime(PrintQueue pq)
{
    Boolean available = true;
    if (pq.StartTimeOfDay != pq.UntilTimeOfDay) // If the printer is not available 24 hours a day
    {
        DateTime utcNow = DateTime.UtcNow;
        Int32 utcNowAsMinutesAfterMidnight = (utcNow.TimeOfDay.Hours * 60) + utcNow.TimeOfDay.Minutes;

        // If now is not within the range of available times . . .
        if (!((pq.StartTimeOfDay < utcNowAsMinutesAfterMidnight)
           &&
           (utcNowAsMinutesAfterMidnight < pq.UntilTimeOfDay)))
        {
            available = false;
        }
    }
    return available;
}//end ReportAvailabilityAtThisTime
Private Shared Function ReportAvailabilityAtThisTime(ByVal pq As PrintQueue) As Boolean
    Dim available As Boolean = True
    If pq.StartTimeOfDay <> pq.UntilTimeOfDay Then ' If the printer is not available 24 hours a day
        Dim utcNow As Date = Date.UtcNow
        Dim utcNowAsMinutesAfterMidnight As Int32 = (utcNow.TimeOfDay.Hours * 60) + utcNow.TimeOfDay.Minutes

        ' If now is not within the range of available times . . .
        If Not((pq.StartTimeOfDay < utcNowAsMinutesAfterMidnight) AndAlso (utcNowAsMinutesAfterMidnight < pq.UntilTimeOfDay)) Then
            available = False
        End If
    End If
    Return available
End Function 'end ReportAvailabilityAtThisTime

Die TimeConverter.ConvertToLocalHumanReadableTime-Methode (im folgenden Codebeispiel dargestellt) verwendet keine Methoden, die mit Microsoft .NET Framework eingeführt wurden, daher ist die Diskussion kurz. Die Methode hat die Aufgabe einer doppelten Konvertierung: Sie muss eine ganze Zahl, die Minuten nach Mitternacht darstellt, in eine für Menschen lesbare Zeit umwandeln und diese dann in die Ortszeit konvertieren. Dies wird erreicht, indem zuerst ein DateTime Objekt erstellt wird, das auf Mitternacht UTC festgelegt ist, und anschließend wird die AddMinutes Methode verwendet, um die Minuten hinzuzufügen, die an die Methode übergeben wurden. Es wird eine neue DateTime Ausgabe zurückgegeben, die die ursprünglich an die Methode übergebene Zeit darstellt. Die ToLocalTime Methode konvertiert dies dann in die Ortszeit.

private ref class TimeConverter {

internal: 
   static DateTime ConvertToLocalHumanReadableTime (Int32 timeInMinutesAfterUTCMidnight) 
   {
      // Construct a UTC midnight object.
      // Must start with current date so that the local Daylight Savings system, if any, will be taken into account.
      DateTime utcNow = DateTime::UtcNow;
      DateTime utcMidnight = DateTime(utcNow.Year, utcNow.Month, utcNow.Day, 0, 0, 0, DateTimeKind::Utc);

      // Add the minutes passed into the method in order to get the intended UTC time.
      Double minutesAfterUTCMidnight = ((Double)timeInMinutesAfterUTCMidnight);
      DateTime utcTime = utcMidnight.AddMinutes(minutesAfterUTCMidnight);

      // Convert to local time.
      DateTime localTime = utcTime.ToLocalTime();

      return localTime;
   };
};
class TimeConverter
{
    // Convert time as minutes past UTC midnight into human readable time in local time zone.
    internal static DateTime ConvertToLocalHumanReadableTime(Int32 timeInMinutesAfterUTCMidnight)
    {
        // Construct a UTC midnight object.
        // Must start with current date so that the local Daylight Savings system, if any, will be taken into account.
        DateTime utcNow = DateTime.UtcNow;
        DateTime utcMidnight = new DateTime(utcNow.Year, utcNow.Month, utcNow.Day, 0, 0, 0, DateTimeKind.Utc);

        // Add the minutes passed into the method in order to get the intended UTC time.
        Double minutesAfterUTCMidnight = (Double)timeInMinutesAfterUTCMidnight;
        DateTime utcTime = utcMidnight.AddMinutes(minutesAfterUTCMidnight);

        // Convert to local time.
        DateTime localTime = utcTime.ToLocalTime();

        return localTime;
    }// end ConvertToLocalHumanReadableTime
}//end TimeConverter class
Friend Class TimeConverter
    ' Convert time as minutes past UTC midnight into human readable time in local time zone.
    Friend Shared Function ConvertToLocalHumanReadableTime(ByVal timeInMinutesAfterUTCMidnight As Int32) As Date
        ' Construct a UTC midnight object.
        ' Must start with current date so that the local Daylight Savings system, if any, will be taken into account.
        Dim utcNow As Date = Date.UtcNow
        Dim utcMidnight As New Date(utcNow.Year, utcNow.Month, utcNow.Day, 0, 0, 0, DateTimeKind.Utc)

        ' Add the minutes passed into the method in order to get the intended UTC time.
        Dim minutesAfterUTCMidnight As Double = CType(timeInMinutesAfterUTCMidnight, Double)
        Dim utcTime As Date = utcMidnight.AddMinutes(minutesAfterUTCMidnight)

        ' Convert to local time.
        Dim localTime As Date = utcTime.ToLocalTime()

        Return localTime

    End Function ' end ConvertToLocalHumanReadableTime

End Class

Siehe auch