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.
Läs egenskaperna StartTimeOfDay och UntilTimeOfDay för PrintQueue för att avgöra om den aktuella tiden är mellan dem.
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 false
om 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
.NET Desktop feedback