Procedure: Ontdekken of een afdruktaak op dit moment van de dag kan worden afgedrukt
Afdrukwachtrijen zijn niet altijd 24 uur per dag beschikbaar. Ze hebben eigenschappen voor begin- en eindtijd die kunnen worden ingesteld om ze op bepaalde tijdstippen van de dag niet beschikbaar te maken. Deze functie kan bijvoorbeeld worden gebruikt om na 17:00 uur een printer te reserveren voor het exclusieve gebruik van een bepaalde afdeling. Die afdeling zou een andere wachtrij hebben om op de printer aan te sluiten dan die welke andere afdelingen gebruiken. De wachtrij voor de andere afdelingen zou na 17:00 uur niet beschikbaar zijn, terwijl de wachtrij voor de favoriete afdeling altijd beschikbaar zou kunnen zijn.
Bovendien kunnen afdruktaken zelf zodanig worden ingesteld dat ze alleen binnen een bepaalde periode kunnen worden afgedrukt.
De PrintQueue- en PrintSystemJobInfo-klassen die beschikbaar zijn in de API's van Microsoft .NET Framework bieden een manier om op afstand te controleren of een bepaalde afdruktaak op het huidige moment kan afdrukken op een bepaalde wachtrij.
Voorbeeld
Het onderstaande voorbeeld is een voorbeeld waarmee problemen met een afdruktaak kunnen worden vastgesteld.
Er zijn twee belangrijke stappen voor dit soort functies als volgt.
Lees de eigenschappen StartTimeOfDay en UntilTimeOfDay van de PrintQueue om te bepalen of de huidige tijd ertussen is.
Lees de eigenschappen StartTimeOfDay en UntilTimeOfDay van de PrintSystemJobInfo om te bepalen of de huidige tijd ertussen is.
Maar complicaties ontstaan door het feit dat deze eigenschappen niet DateTime objecten zijn. In plaats daarvan zijn het Int32 objecten die de tijd uitdrukken in het aantal minuten sinds middernacht. Bovendien is dit niet middernacht in de huidige tijdzone, maar middernacht UTC (Coordinated Universal Time).
In het eerste codevoorbeeld wordt de statische methode ReportQueueAndJobAvailabilitygepresenteerd, waaraan een PrintSystemJobInfo wordt doorgegeven en die helpermethoden aanroept om te bepalen of de taak op dit moment kan worden afgedrukt, en zo niet, wanneer deze kan worden afgedrukt. U ziet dat een PrintQueue niet wordt doorgegeven aan de methode. Dit komt doordat de PrintSystemJobInfo een verwijzing naar de wachtrij in de eigenschap HostingPrintQueue bevat.
De onderliggende methoden omvatten de overbelaste ReportAvailabilityAtThisTime methode die een PrintQueue of een PrintSystemJobInfo als parameter kan nemen. Er is ook een TimeConverter.ConvertToLocalHumanReadableTime. Al deze methoden worden hieronder besproken.
De methode ReportQueueAndJobAvailability begint met het controleren of de wachtrij of de afdruktaak op dit moment niet beschikbaar is. Als een van deze twee niet beschikbaar is, wordt gecontroleerd of de wachtrij niet beschikbaar is. Als deze niet beschikbaar is, rapporteert de methode dit feit en het tijdstip waarop de wachtrij weer beschikbaar is. Vervolgens wordt de taak gecontroleerd en als deze niet beschikbaar is, wordt de volgende periode gerapporteerd wanneer deze kan worden afgedrukt. Ten slotte rapporteert de methode de vroegste tijd waarop de taak kan worden afgedrukt. Dit is de latere van de volgende twee tijdstippen.
Het tijdstip waarop de afdrukwachtrij de volgende keer beschikbaar is.
Het tijdstip waarop de afdruktaak de volgende keer beschikbaar is.
Bij rapportagetijden van de dag wordt de ToShortTimeString methode ook aangeroepen omdat deze methode de jaren, maanden en dagen van de uitvoer onderdrukt. U kunt de beschikbaarheid van een afdrukwachtrij of een afdruktaak niet beperken tot bepaalde jaren, maanden of dagen.
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 twee overbelastingen van de ReportAvailabilityAtThisTime methode zijn identiek, met uitzondering van het type dat eraan is doorgegeven, dus alleen de PrintQueue versie wordt hieronder weergegeven.
Notitie
Het feit dat de methoden identiek zijn, met uitzondering van het type, stelt de vraag waarom het voorbeeld geen algemene methode maakt ReportAvailabilityAtThisTime<T>. De reden hiervoor is dat een dergelijke methode moet worden beperkt tot een klasse met de eigenschappen StartTimeOfDay en UntilTimeOfDay die door de methode worden aangeroepen, maar een algemene methode kan slechts worden beperkt tot één klasse en de enige klasse die voor zowel PrintQueue als PrintSystemJobInfo in de overnamestructuur geldt, is PrintSystemObject die geen dergelijke eigenschappen heeft.
De methode ReportAvailabilityAtThisTime (weergegeven in het onderstaande codevoorbeeld) begint met het initialiseren van een Boolean sentinel-variabele naar true
. De wachtrij wordt opnieuw ingesteld op false
als de wachtrij niet beschikbaar is.
Vervolgens controleert de methode of de begin- en 'until'-tijden identiek zijn. Als dat zo is, is de wachtrij altijd beschikbaar, zodat de methode true
retourneert.
Als de wachtrij niet altijd beschikbaar is, gebruikt de methode de eigenschap statische UtcNow om de huidige tijd op te halen als een DateTime-object. (We hebben geen lokale tijd nodig omdat de StartTimeOfDay en UntilTimeOfDay eigenschappen zich in UTC-tijd bevinden.)
Deze twee eigenschappen zijn echter niet DateTime objecten. Ze zijn Int32's, die de tijd uitdrukken als het aantal minuten na UTC-middernacht. Dus we moeten ons DateTime object converteren naar minuten na middernacht. Wanneer dat gebeurt, controleert de methode gewoon of 'nu' tussen de begin- en 'until'-tijden van de wachtrij ligt, stelt de sentinel in op false als 'nu' niet tussen de twee keer ligt en de sentinel retourneert.
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
De TimeConverter.ConvertToLocal HumanReadableTime methode (gepresenteerd in het onderstaande codevoorbeeld) gebruikt geen methoden die zijn geïntroduceerd met Microsoft .NET Framework, dus de discussie is kort. De methode heeft een dubbele conversietaak: het moet een geheel getal nemen dat minuten na middernacht uitdrukt en omzetten naar een voor mensen leesbare tijd en het moet dit omzetten naar de lokale tijd. Dit doet u door eerst een DateTime-object te maken dat is ingesteld op middernacht UTC en vervolgens de methode AddMinutes gebruikt om de minuten toe te voegen die aan de methode zijn doorgegeven. Hiermee wordt een nieuwe DateTime geretourneerd waarmee de oorspronkelijke tijd wordt weergegeven die aan de methode is doorgegeven. De methode ToLocalTime converteert dit vervolgens naar lokale tijd.
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
Zie ook
.NET Desktop feedback