Udostępnij za pośrednictwem


Jak wykryć czy zadanie drukowania może zostać zrealizowane o tej porze dnia

Kolejki wydruku nie zawsze są dostępne przez 24 godziny dziennie. Mają właściwości godziny rozpoczęcia i zakończenia, które można ustawić, aby były niedostępne w określonych porach dnia. Tej funkcji można na przykład użyć do zarezerwowania drukarki do wyłącznego użytku określonego działu po godzinie 17:00. Ten dział miałby inną obsługę kolejki drukarki niż używane przez inne działy. Kolejka dla innych działów będzie niedostępna po godzinie 17:00, podczas gdy kolejka dla preferowanego działu może być dostępna przez cały czas.

Ponadto zadania drukowania można ustawić tak, aby można je było drukować tylko w określonym przedziale czasu.

Klasy PrintQueue i PrintSystemJobInfo uwidocznione w interfejsach API programu Microsoft .NET Framework zapewniają metodę zdalnego sprawdzania, czy dane zadanie drukowania może drukować w danej kolejce w bieżącej chwili.

Przykład

Poniższy przykład to przykład, który może diagnozować problemy z zadaniem drukowania.

Istnieją dwa główne kroki dla tego rodzaju funkcji w następujący sposób.

  1. StartTimeOfDay Przeczytaj właściwości i UntilTimeOfDay elementu , PrintQueue aby określić, czy bieżący czas jest między nimi.

  2. StartTimeOfDay Przeczytaj właściwości i UntilTimeOfDay elementu , PrintSystemJobInfo aby określić, czy bieżący czas jest między nimi.

Ale komplikacje wynikają z faktu, że te właściwości nie DateTime są obiektami. Zamiast tego są Int32 obiektami, które wyrażają godzinę dnia jako liczbę minut od północy. Ponadto nie jest to północ w bieżącej strefie czasowej, ale o północy UTC (uniwersalny czas koordynowany).

Pierwszy przykład kodu przedstawia metodę statyczną ReportQueueAndJobAvailability, która jest przekazywana PrintSystemJobInfo metodą pomocnika i wywołuje metody pomocnika w celu określenia, czy zadanie może drukować w bieżącym czasie i, jeśli nie, kiedy można go wydrukować. Zwróć uwagę, że element PrintQueue nie jest przekazywany do metody . Jest to spowodowane tym, że PrintSystemJobInfo element zawiera odwołanie do kolejki we właściwości HostingPrintQueue .

Metody podrzędne obejmują przeciążone metody ReportAvailabilityAtThisTime , która może przyjmować PrintQueue parametr lub jako PrintSystemJobInfo parametr. Istnieje również timeConverter.ConvertToLocalHumanReadableTime. Wszystkie te metody zostały omówione poniżej.

Metoda ReportQueueAndJobAvailability rozpoczyna się od sprawdzenia, czy kolejka lub zadanie drukowania jest obecnie niedostępne. Jeśli którykolwiek z nich jest niedostępny, sprawdza, czy kolejka jest niedostępna. Jeśli nie jest dostępna, metoda zgłasza ten fakt i czas ponownego udostępnienia kolejki. Następnie sprawdza zadanie i jeśli jest niedostępne, raportuje następny przedział czasu, kiedy będzie mógł drukować. Na koniec metoda zgłasza najwcześniejszą godzinę drukowania zadania. Jest to późniejsze dwa razy.

  • Czas, kiedy kolejka wydruku jest dostępna dalej.

  • Godzina następnego udostępnienia zadania drukowania.

W przypadku raportowania godzin dnia metoda jest również wywoływana, ToShortTimeString ponieważ ta metoda pomija lata, miesiące i dni z danych wyjściowych. Nie można ograniczyć dostępności kolejki wydruku lub zadania drukowania do określonych lat, miesięcy lub dni.

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

Dwa przeciążenia metody ReportAvailabilityAtThisTime są identyczne z wyjątkiem typu przekazanego do nich, więc poniżej przedstawiono tylko PrintQueue wersję.

Uwaga

Fakt, że metody są identyczne z wyjątkiem typu, rodzi pytanie, dlaczego próbka nie tworzy metody ogólnej ReportAvailabilityAtThisTime<T>. Powodem jest to, że taka metoda musiałaby być ograniczona do klasy, która ma właściwości StartTimeOfDay i UntilTimeOfDay , które metoda wywołuje, ale metoda ogólna może być ograniczona tylko do pojedynczej klasy i jedyną klasą wspólną dla obu i PrintQueuePrintSystemJobInfo w drzewie dziedziczenia, która PrintSystemObject nie ma takich właściwości.

Metoda ReportAvailabilityAtThisTime (przedstawiona w poniższym przykładzie kodu) rozpoczyna się od zainicjowania zmiennej Boolean sentinel na true. Jeśli kolejka nie jest dostępna, zostanie zresetowana do false.

Następnie metoda sprawdza, czy czas rozpoczęcia i "do" są identyczne. Jeśli są, kolejka jest zawsze dostępna, więc metoda zwraca truewartość .

Jeśli kolejka nie jest dostępna przez cały czas, metoda używa właściwości statycznej UtcNow , aby uzyskać bieżący czas jako DateTime obiekt. (Nie potrzebujemy czasu lokalnego, ponieważ StartTimeOfDay właściwości i UntilTimeOfDay są same w czasie UTC).

Te dwie właściwości nie DateTime są jednak obiektami. Wyrażają Int32one czas jako liczbę minut po utc-północy. Musimy więc przekonwertować nasz DateTime obiekt na minuty po północy. Po wykonaniu tej czynności metoda po prostu sprawdza, czy "teraz" znajduje się między godzinami rozpoczęcia kolejki i "do" ustawia wartość false, jeśli wartość "now" nie występuje między dwoma razy i zwraca wartość sentinel.

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

Metoda TimeConverter.ConvertToLocalHumanReadableTime (przedstawiona w poniższym przykładzie kodu) nie używa żadnych metod wprowadzonych w programie Microsoft .NET Framework, więc dyskusja jest krótka. Metoda ma zadanie konwersji podwójnej: musi upłynąć liczba całkowita wyrażana minut po północy i przekonwertować ją na czas czytelny dla człowieka i musi przekonwertować ją na czas lokalny. Jest to realizowane przez najpierw utworzenie obiektu ustawionego DateTime na północ czasu UTC, a następnie użycie AddMinutes metody w celu dodania minut przekazanych do metody . Spowoduje to zwrócenie nowego DateTime wyrażenia oryginalnego czasu przekazanego do metody . Następnie ToLocalTime metoda konwertuje tę metodę na czas lokalny.

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

Zobacz też