Dela via


Anvisningar: Identifiera om ett utskriftsjobb kan skrivas ut vid den här tiden på dagen

Utskriftsköer är inte alltid tillgängliga 24 timmar om dygnet. De har start- och sluttidsegenskaper som kan anges för att göra dem otillgängliga vid vissa tidpunkter på dagen. Den här funktionen kan till exempel användas för att reservera en skrivare för exklusiv användning av en viss avdelning efter 17.00. Den avdelningen skulle ha en annan kö för skrivaren än den som andra avdelningar använder. Kön för de andra avdelningarna skulle ställas in så att den är otillgänglig efter 17.00, medan kön för den gynnade avdelningen skulle kunna vara tillgänglig hela tiden.

Utskriftsjobb kan dessutom ställas in så att de endast kan skrivas ut inom en angiven tidsperiod.

Klasserna PrintQueue och PrintSystemJobInfo som exponeras i API:erna för Microsoft .NET Framework är ett sätt att fjärrkontrollera om ett visst utskriftsjobb kan skrivas ut i en viss kö vid den aktuella tidpunkten.

Exempel

Exemplet nedan är ett exempel som kan diagnostisera problem med ett utskriftsjobb.

Det finns två viktiga steg för den här typen av funktion enligt följande.

  1. Läs egenskaperna StartTimeOfDay och UntilTimeOfDay för PrintQueue för att avgöra om den aktuella tiden är mellan dem.

  2. Läs egenskaperna StartTimeOfDay och UntilTimeOfDay för PrintSystemJobInfo för att avgöra om den aktuella tiden är mellan dem.

Men komplikationer uppstår från det faktum att dessa egenskaper inte är DateTime objekt. I stället är de Int32 objekt som uttrycker tiden på dagen som antalet minuter sedan midnatt. Dessutom är detta inte midnatt i den aktuella tidszonen, utan midnatt UTC (Coordinated Universal Time).

I det första kodexemplet visas den statiska metoden ReportQueueAndJobAvailability, som skickas en PrintSystemJobInfo och anropar hjälpmetoder för att avgöra om jobbet kan skrivas ut vid den aktuella tidpunkten och, om inte, när det kan skrivas ut. Observera att en PrintQueue inte skickas till metoden. Detta beror på att PrintSystemJobInfo innehåller en referens till kön i sin HostingPrintQueue-egenskap.

De underordnade metoderna omfattar den överlagrade metoden ReportAvailabilityAtThisTime, som kan ta antingen en PrintQueue eller en PrintSystemJobInfo som parameter. Det finns även en TimeConverter.ConvertToLocalHumanReadableTime. Alla dessa metoder beskrivs nedan.

Metoden ReportQueueAndJobAvailability börjar med att kontrollera om antingen kön eller utskriftsjobbet är otillgängligt just nu. Om någon av dem inte är tillgänglig, kontrollerar systemet om kön är otillgänglig. Om den inte är tillgänglig rapporterar metoden det här faktumet och tiden då kön blir tillgänglig igen. Det kontrollerar sedan jobbet och om det inte är tillgängligt rapporterar det nästa tidsintervall när det kan skrivas ut. Slutligen rapporterar metoden den tidigaste tiden då jobbet kan skrivas ut. Detta är det senare av följande två gånger.

  • Den tid då utskriftskön nästa gång är tillgänglig.

  • Tidpunkten när utskriftsjobbet nästa gång kommer att vara tillgängligt.

När du rapporterar tider på dagen anropas även metoden ToShortTimeString eftersom den här metoden undertrycker år, månader och dagar från utdata. Du kan inte begränsa tillgängligheten för en utskriftskö eller ett utskriftsjobb till specifika år, månader eller dagar.

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

De två överlagringarna av metoden ReportAvailabilityAtThisTime är identiska förutom typen som skickas till dem, så endast versionen PrintQueue visas nedan.

Not

Det faktum att metoderna är identiska förutom typ väcker frågan om varför exemplet inte skapar en generisk metod ReportAvailabilityAtThisTime<T>. Anledningen är att en sådan metod måste begränsas till en klass som har StartTimeOfDay och UntilTimeOfDay egenskaper som metoden anropar, men en allmän metod kan endast begränsas till en enda klass och den enda klass som är gemensam för både PrintQueue och PrintSystemJobInfo i arvsträdet är PrintSystemObject som inte har några sådana egenskaper.

Metoden ReportAvailabilityAtThisTime (visas i kodexemplet nedan) börjar med att initiera en Boolean sentinel-variabel till true. Det återställs till falseom kön inte är tillgänglig.

Därefter kontrollerar metoden om start- och "till"-tiderna är identiska. Om så är fallet är kön alltid tillgänglig, så metoden returnerar true.

Om kön inte är tillgänglig hela tiden använder metoden den statiska egenskapen UtcNow för att hämta aktuell tid som ett DateTime-objekt. (Vi behöver inte lokal tid eftersom egenskaperna StartTimeOfDay och UntilTimeOfDay själva är i UTC-tid.)

Dessa två egenskaper är dock inte DateTime objekt. De är Int32och uttrycker tiden som antalet minuter efter midnatt UTC. Så vi måste konvertera vårt DateTime-objekt till minuter efter midnatt. När det är klart kontrollerar metoden helt enkelt om "nu" är mellan köns starttid och "till"-tid, sätter sentinel till false om "nu" inte är mellan de två tiderna, och returnerar 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

Metoden TimeConverter.ConvertToLocalHumanReadableTime (presenteras i kodexemplet nedan) använder inte några metoder som introduceras med Microsoft .NET Framework, så diskussionen är kort. Metoden har en dubbel konverteringsuppgift: den måste ta ett heltal som uttrycker minuter efter midnatt och konvertera det till en läsbar tid samt omvandla det till lokal tid. Det åstadkommer detta genom att först skapa ett DateTime objekt som är inställt på midnatts-UTC och sedan använder metoden AddMinutes för att lägga till de minuter som skickades till metoden. Detta returnerar en ny DateTime som uttrycker den ursprungliga tiden som skickades till metoden. Metoden ToLocalTime konverterar sedan detta till lokal tid.

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

Se även