Gewusst wie: Ermitteln, 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. Dieses Feature kann z. B. verwendet werden, um einen Drucker für die exklusive Nutzung einer bestimmten Abteilung nach 5 P.M. zu reservieren. Diese Abteilung hätte eine andere Warteschlangenwartung für den Drucker als andere Abteilungen. Die Warteschlange für die anderen Abteilungen wäre nach 5 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.

PrintQueue Die PrintSystemJobInfo in den APIs von Microsoft .NET Framework verfügbar gemachten Klassen bieten eine Möglichkeit, remote zu überprüfen, ob ein gegebener Druckauftrag zum aktuellen Zeitpunkt in einer bestimmten Warteschlange gedruckt werden 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 StartTimeOfDay Eigenschaften und UntilTimeOfDay Eigenschaften der PrintQueue, um zu bestimmen, ob sich die aktuelle Zeit zwischen ihnen befindet.

  2. Lesen Sie die StartTimeOfDay Eigenschaften und UntilTimeOfDay Eigenschaften der 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 handelt es sich bei Int32 um Objekte, die die Tageszeit als Die 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 dargestellt, die eine PrintSystemJobInfo Hilfsmethode übergeben und 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 PrintSystemJobInfo einen Verweis auf die Warteschlange in seiner HostingPrintQueue Eigenschaft enthalten ist.

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

Die ReportQueueAndJobAvailability-Methode beginnt mit der Überprüfung, ob die Warteschlange oder der Druckauftrag zurzeit nicht verfügbar ist. Wenn eine dieser Optionen 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 wird der Auftrag überprüft, und wenn er nicht verfügbar ist, meldet er den nächsten Zeitraum, wenn er gedruckt werden kann. Schließlich meldet die Methode die früheste Zeit, zu der der Auftrag gedruckt werden kann. Dies ist der spätere von zwei Mal.

  • Die Zeit, zu der die Druckwarteschlange als nächstes verfügbar ist.

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

Wenn Sie Tageszeiten melden, wird die ToShortTimeString Methode auch aufgerufen, da diese Methode die Jahre, Monate und Tage von der Ausgabe unterdrückt. 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 nur die PrintQueue Version unten dargestellt wird.

Hinweis

Die Tatsache, dass die Methoden mit Ausnahme des Typs identisch sind, löst die Frage aus, warum das Beispiel keine generische Methode ReportAvailabilityAtThisTimeT<> erstellt. Der Grund dafür ist, dass eine solche Methode auf eine Klasse beschränkt werden müsste, die die Eigenschaften StartTimeOfDay und UntilTimeOfDay besitzt, die die Methode aufruft. Eine generische Methode kann jedoch nur auf eine einzige Klasse beschränkt werden, und die einzige Klasse, die beiden PrintQueue und PrintSystemJobInfo gemeinsam ist und sich im PrintSystemObject Vererbungsbaum befindet, besitzt keine dieser Eigenschaften.

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

Als nächstes prüft die Methode, ob die Start- und die "bis"-Zeit identisch sind. Wenn sie vorhanden 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 sich die StartTimeOfDay Eigenschaften UntilTimeOfDay selbst in UTC-Zeit befinden.)

Diese beiden Eigenschaften sind jedoch keine DateTime Objekte. Es sind Int32, die die Zeit als die Anzahl der Minuten nach Mitternacht angeben. Daher müssen wir unser DateTime Objekt in Minuten nach Mitternacht konvertieren. Wenn dies geschehen ist, überprüft die Methode einfach, ob "jetzt" zwischen dem Start- und "bis" Uhrzeit 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, sodass die Diskussion kurz ist. Die Methode hat eine doppelte Konvertierungsaufgabe: Es muss eine ganze Zahl dauern, die Minuten nach Mitternacht ausgedrückt wird, und sie in eine von Menschen lesbare Zeit konvertieren und dies in die lokale Zeit konvertieren muss. Dies wird erreicht, indem zuerst ein DateTime Objekt erstellt wird, das auf Mitternacht UTC festgelegt ist, und dann wird die AddMinutes Methode verwendet, um die Minuten hinzuzufügen, die an die Methode übergeben wurden. Dadurch wird ein neuer DateTime Ausdruck der ursprünglichen Zeit zurückgegeben, die an die Methode übergeben wurde. Die ToLocalTime Methode konvertiert dies dann in die lokale Zeit.

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

Weitere Informationen