Hardloop klas as nuwe draad
-
03-07-2019 - |
Vra
Ek wil 'n werk te begin in 'n nuwe draad of die gebruik van Background om dit te doen, maar havent gedoen wat voor en vra dat jy daaronder manier wat ek moet dit doen.
My program het 'n datagridview met 'n lys van lêers, 'n lêer per ry. Ek wil die gebruiker in staat wees om 'n ry te kies en druk dan op "Begin aflaai" om 'n agtergrond werk van die aflaai begin. Ek wil gebeure agterkant van die vordering van die aflaai te kry.
Ek het 'n klas clsDownload dat alles hanteer en verhoog gebeure terug, maar hoe kan ek die backgroundworking implementeer?
Indien ek gebruik die System.ComponentModel.BackgroundWorker binnekant van die klas of skep 'n paar wikkel dat hierdie hanteer of gebruik 'n ander threading dinge?
Dankie.
Edit: Ek dont weet hoe om my af te laai in die Background implementeer, enige klein voorbeeld sou baie lekker wees. Die voorbeeld op MSDN didnt my ver kom nie.
Ek het 'n aflaai klas wat 'n StartDownload-funksie het. Moet ek gebruik die Background IN die klas of in die oproeper? "Voel dom"
Oplossing
Ek het 'n paar verskillende klasse wat Background inkorporeer geskep. Wat ek oor die algemeen doen, is 'n Background komponent op die vorm wat oop sal wees wanneer die werk word uitgevoer, dan slaag ek dat byvoorbeeld die konstruktor van my werk klas.
Hier is wat jou werk klas kan lyk:
Private m_bwMain As BackgroundWorker
Public Sub New(ByVal bwMain As BackgroundWorker)
m_bwMain = bwMain
'additional setup code here
End Sub
Om 'n werk te begin, sal jy so iets doen in die Click event handler van jou Start aflaai knoppie:
lblStatus.Text = "Initializing ..."
bgwMain.RunWorkerAsync(someFileName)
Ek verklaar my werk klas as 'n private lid van die huidige vorm, dan instansieer dit in die BackgroundWorker.DoWork gebeurtenis. Van daar kan jy jou metode te roep om 'n lêer af te laai:
Private Sub bgwMain_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgwMain.DoWork
m_oJobEngine = New JobEngine(CType(sender, BackgroundWorker))
m_oJobEngine.DownloadFile(CStr(e.Argument))
End Sub
Om vorderingsverslag aan die gebruiker, kan jy dit hanteer die gebeure wat deur jou klas in jou kop vorm. Jy hoef net om seker te maak die werk verklaring klas voorwerp het die WithEvents navraag. Van dié hanteerders jy kan die ReportProgress metode van Background noem. Van binne ReportProgress jy kan maak ongeag veranderinge wat jy nodig het om die UI om vordering aan te dui. Hier is 'n voorbeeld:
Private Sub m_oJobEngine.DownloadProgress(ByVal bgw as Backgroundworker, ByVal bytesTransferred as Long) Handles m_oJobEngine.DownloadProgress
bgw.ReportProgress(0, bytesTransferred)
End Sub
Private Sub bgwMain_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bgwMain.ProgressChanged
lblStatus.Text = CLng(e.UserState).ToString & " bytes transferred."
End Sub
Hoop dit help.
Ander wenke
Ek julle net gaan doen te laai en moenie ander asinkroniseer verwerking nie nodig, jy kan net gebruik die asinkroniseer metodes van die WebClient
klas. Hoewel sedert jy reeds jou eie klas, dit is waarskynlik nie 'n oplossing vir jou.
Anders, kan jy gebruik BackgroundWorker
as jy genoem. Die bladsy MSDN het 'n voorbeeld hoe om dit te doen.
Edit: Die kortverhaal is:
- Jy skep die
BackgroundWorker
van die oproeper; - As jy wil die agtergrond werk begin, jy
BackgroundWorker.RunWorkerAsync
noem; - in die
DoWork
event handler jy die agtergrond werk doen, in jou geval jy jou aflaai klas begin - terwyl jy doen die agtergrond werk, moet jy elke keer so 'n rukkie vir
CancelationPending
; - wanneer jy wil 'n paar vorderingsverslag, moet jy om dit te bereken in persentasie en noem
ReportProgress
.
As jy iets regtig aangepas nodig het, kan jy altyd jou eie Thread
.
Ek persoonlik sou hou met BackgroundWorker
. Dit het 'n mooi stel kennisgewings vir verskillende stadiums van die werk. As jy Thread
gebruik, sal jy het om hierdie win implementeer.
Ek wil ook seker maak dat die kode nie te veel gevalle skep. Jy wil die aantal concurent downloads beperk en ry enigiets verlede dat die getal.
Ek sal raai BackgroundWorker
as jy nodig het om terugvoer te gee aan die gebruiker op die UI. Die ProgressChanged
en RunWorkerCompleted
gebeure hardloop op die UI draad, so daar is geen behoefte om ordening te doen, wat jou kode meer kompleks kan maak.
Die Background lyk soos dit moet werk ... Daar is 'n voorbeeld van MSDN.
http://msdn.microsoft.com/en -us / library / system.componentmodel.backgroundworker.aspx
Of jy kan iets soos te doen:
WaitCallBack workCallBack= new WaitCallBack(DownloadMethod);
if(!ThreadPool.QueueUserWorkItem(workCallBack, "ThreadPooled")
{
// Unable to Pool
}
// Work has been added to pool and will execute when possible
Dit hang af wat parameters indien enige wat jy nodig het vir die onderwerp.
Die klas wat clsDownload (waarskynlik u Form klas) gebruik moet Background gebruik om die aflaai metode loop.