2016-05-06 5 views
0

Ich möchte Arbeiter in eine Warteschlange hinzufügen, aber nur die ersten N Arbeiter parallel verarbeiten. Alle Samples, die ich finde, sind in C#.Ich brauche Hilfe beim Erstellen eines TaskScheduler, um Threading Überlastung zu vermeiden

Dieses ist für einen Programmierer wahrscheinlich einfach, aber ich bin ein nicht. Ich weiß genug über VB, um einfache Programme zu schreiben.

Aber meine erste Anwendung läuft gut, bis es plötzlich 100% CPU trifft und dann abstürzt. Hilfe, bitte (Ja, ich habe 5 Stunden Arbeitssuche vergeudet, bevor ich das poste ...)

Mehr Kontext: Durchführen einer rekursiven Inventarisierung von Verzeichnisstrukturen, Dateien und Berechtigungen über Dateiserver mit über 1 Million Verzeichnissen/Unterverzeichnisse.

Der Prozess wird seriell ausgeführt, dauert jedoch Monate. Management atmet schon an meinem Hals. Wenn ich versuche, Tasks zu verwenden, geht es zu etwa 1000 Threads, dann trifft 100% CPU, reagiert nicht mehr und stürzt dann ab. Dies ist auf einem 16-Core-Server mit 112 GB RAM.

--Added Also, mit der Probe zur Verwendung von Semaphoren zur Verfügung gestellt, das ist, was ich setze in:

Public Class InvDir 
    Private mSm as Semaphore 
    Public Sub New(ByVal maxPrc As Integer) 
     mSm = New Semaphore(maxPrc, maxPrc) 
    End Sub 

    Public Sub GetInventory(ByVal Path As String, ByRef Totals As Object, ByRef MyData As Object) 
     mSm.WaitOne() 

     Task.Factory.StartNew(Sub() 
       Dim CurDir As New IO.DirectoryInfo(Path) 
       Totals.SubDirectoryCount += CurDir.GetDirectories().Count 
       Totals.FilesCount += CurDir.GetFiles().Count 
       For Each CurFile As IO.FileInfo in CurDir.EnumerateFiles() 
        MyData.AddFile(CurFile.FileName, CurFile.Extension, CurFile.FullName, CurFile.Length) 
       Next 
       End Sub).ContinueWith(Function(x) mSm.Release()) 
    End Sub 
End Class 
+1

Sagen Sie "Management", um einen Berater einzustellen. – Plutonix

+0

Ihre Frage ist viel zu weit gefasst und wir können nicht erklären, warum Code, den wir nicht sehen können, sich nicht richtig verhält. Wir werden keinen Aufgabenplaner für Sie schreiben, und wir sind keine Tutorial-Site, auf der wir Ihnen das beibringen können. Wenn Sie * genug über VB wissen, um einfache Programme * zu schreiben, müssen Sie über Ihre derzeitigen Fähigkeiten hinausgehen und Sie müssen dem Management mitteilen, dass Sie Hilfe benötigen, damit sie einen Auftragnehmer oder Programmierer einstellen können. –

+0

Ich bitte niemanden, einen "Task Scheduler" zu schreiben. Es gibt ein TaskScheduler OBJECT in .NET und der gesamte Beispielcode, den ich finde, wie man ihn benutzt, ist in C#. Ich habe nur gefragt, wie man es in VB.NET macht. Ich gebe ein, was ich mache, um einen Kontext zu geben, nicht um jemanden, der meine Arbeit für mich erledigt. Ich habe versucht, eine Sammlung von Task-Objekten und die Parallel.ForEach-Methoden zu verwenden, aber sie nehmen bald alle Threads auf. – HelpThisisNOTmyJob

Antwort

1

Sie versuchen, mit Platten Multithreading I/O. Es könnte langsamer werden weil Sie werfen mehr Threads bei ihm. Unabhängig davon, wie viele Threads vorhanden sind, kann die Festplatte physisch jeweils nur eine Position suchen. (In der Tat haben Sie erwähnt, dass es seriell funktioniert.)

Wenn Sie die Anzahl der gleichzeitigen Threads begrenzen möchten, können Sie eine Semaphore verwenden. Ein Semaphor ist wie ein syncLock, außer dass Sie angeben können, wie viele Threads den Code gleichzeitig ausführen dürfen. Im folgenden Beispiel ermöglicht der Semaphor die Ausführung von drei Threads. Mehr als das muss warten, bis einer fertig ist. Einige modifizierte Code von der MSDN-Seite:

Public Class Example 

    ' A semaphore that simulates a limited resource pool. 
    ' 
    Private Shared _pool As Semaphore 

    <MTAThread> _ 
    Public Shared Sub Main() 
     ' Create a semaphore that can satisfy up to three 
     ' concurrent requests. Use an initial count of zero, 
     ' so that the entire semaphore count is initially 
     ' owned by the main program thread. 
     ' 
     _pool = New Semaphore(0, 3)   

    End Sub 

    Private Sub SomeWorkerMethod() 
     'This is the method that would be called using a Task. 
     _pool.WaitOne() 
     Try 
      'Do whatever 
     Finally 
      _pool.Release() 
     End Try 
    End Sub 
End Class 

Jeder neue Thread muss _pool.WaitOne() nennen. Das bedeutet, dass es warten muss, bis weniger als drei Threads ausgeführt werden. Jeder Thread blockiert, bis der Semaphor es passieren lässt.

Jeder Thread muss auch _pool.Release() nennen die Semaphore wissen zu lassen, dass es die nächste wartenden Thread erlauben kann zu beginnen. Das ist wichtig, auch wenn es eine Ausnahme gibt. Wenn Threads nicht Release() aufrufen, blockiert der Semaphor sie für immer.

Wenn es geht wirklich fünf Monate dauern, was ist das Laufwerk Klonen und die Prüfung auf mehrere Instanzen des gleichen Laufwerk ausgeführt wird, die jeweils an verschiedenen Abschnitten suchen?

+0

Danke. Das ist hilfreich. Ich habe auch gefunden, dass der TaskScheduler innerhalb des ThreadPool ist. Es kann mithilfe von ThreadPool.SetMaxthreads() eingeschränkt werden. – HelpThisisNOTmyJob

+0

Das ist wahrscheinlich eine bessere Lösung. Sie sind besser darin geworden, obskure Dinge wie das Semaphor zu nehmen und einfachere, intuitivere Wege zu bieten, dasselbe zu tun. –

Verwandte Themen