Ich habe eine Klasse WorkQueue
, nur zur Kenntnis nehmen über die DoNext()
für jetzt, der Rest sind hauptsächlich Helfer. Grundsätzlich ist WorkQueue
nur eine Warteschlange von WorkItems
. DoNext()
ist verantwortlich für "Starten eines ausstehenden Arbeitselements mit einem freien Hintergrund Worker". Beachten Sie auch, dass die Eigenschaft WorkItem.Worker
festgelegt wird.Brauchen Sie Hilfe Debuggen, warum Eigenschaft nicht gesetzt ist/null
public class WorkQueue<Tin, Tout> :
INotifyCollectionChanged, IEnumerable<WorkItem<Tin, Tout>>
{
public bool DoNext()
{
// check if any work left in queue
WorkItem<Tin, Tout> item = GetWork();
if (item != null)
{
// check if any free workers
BackgroundWorker worker = GetWorker();
Debug.WriteLine(
"[WorkQueue.DoNext] Setting Worker to WorkItem: " + worker);
item.Worker = worker;
if (worker != null)
{
worker.RunWorkerAsync(item);
return true;
}
}
return false;
}
public void AddWork(WorkItem<Tin, Tout> item)
{
_queue.Add(item);
RaiseCollectionChanged(
new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Add, item));
}
public WorkItem<Tin, Tout> GetWork()
{
return (from i in _queue
where i.Status == WorkStatus.Pending
select i).FirstOrDefault();;
}
public BackgroundWorker GetWorker()
{
return (from worker in _workers
where worker.IsBusy == false
select worker).FirstOrDefault();
}
}
Das Problem, das ich habe, ist, wenn ich etwas tun, wie unten,
foreach (string filename in fileNames) {
UploadQueue.AddWork(new WorkItem<string, UploadedImage>(filename));
UploadQueue.DoNext();
}
Wo UploadQueue
ein WorkQueue<string, UploadedImage>
ist. Auf der ersten (nur ersten) DoNext()
ist die WorkItem.Worker
Null. Ich weiß das, weil meine Abbrechen-Schaltfläche, die an WorkItem.CancelCommand
gebunden ist, deaktiviert ist. Beim Debugging stellte ich fest, dass der Grund darin lag, dass der Worker null ist.
_cancelCommand = new RelayCommand(...() =>
{
// Returns true if WorkItem is being processed with a worker that supports
// cancellation or if the WorkItem is still Pending
// False if otherwise, eg. already completed, cancelled etc
if (Status == WorkStatus.Processing)
{
if (_worker != null && _worker.WorkerSupportsCancellation)
return true;
} else if (Status == WorkStatus.Pending) {
return true;
}
return false;
});
Die Lösung ist die DoNext()
aus der Schleife zu bewegen,
foreach (string filename in fileNames)
UploadQueue.AddWork(new WorkItem<string, UploadedImage>(filename));
UploadQueue.DoNext();
aber was ist das Problem mit ihm nach innen, warum Arbeiter auf null gesetzt wird? Wenn sein Null, von der if-Klausel, sollte die BackgroundWorker
nicht starten?
if (worker != null)
worker.RunWorkerAsync(item);
Video Demonstrating the Problem
bekommen, die nicht ist, wie ich verwenden würde Hintergrund Arbeiter ... –
Wann ist die Prüfung für den Button Status? Und wo passt der _cancelCommand? – Doggett
Nur ein Vorschlag, haben Sie daran gedacht, stattdessen Aufgaben zu verwenden? –