C # A-sinkroniseer - Hoe werk dit?
-
27-09-2019 - |
Vra
Microsoft aangekondig dat die Visual Studio A-sinkroniseer CTP vandag (28 Oktober 2010) wat stel die async
en await
sleutelwoorde in C # / VB vir asinchrone metode uitvoering.
Ek het eers gedink dat die samesteller vertaal die sleutelwoorde in die skepping van 'n draad, maar volgens die witskrif en Anders Hejlsberg se PDC aanbieding (by 31:00) die asynchrone operasie gebeur heeltemal op die hoof draad.
Hoe kan ek 'n operasie uitgevoer in parallel op dieselfde draad? Hoe is dit tegnies moontlik en om dit wat die funksie eintlik vertaal in IL?
Oplossing
Dit werk soortgelyk aan die yield return
navraag in C # 2,0.
'n asinchrone metode is nie eintlik 'n gewone opeenvolgende metode. Dit is saamgestel in 'n toestand masjien ( 'n voorwerp) met 'n paar staat (plaaslike veranderlikes verander in velde van die voorwerp). Elke blok kode tussen twee gebruike van await
is een "stap" van die staat masjien.
Dit beteken dat wanneer die metode begin, is dit net die eerste stap loop en dan die staat masjien opbrengste en skedules bietjie werk wat gedoen moet word - wanneer die werk gedoen word, sal dit die volgende stap van die staat masjien loop. Byvoorbeeld hierdie kode:
async Task Demo() {
var v1 = foo();
var v2 = await bar();
more(v1, v2);
}
sou wees vertaalde iets soos:
class _Demo {
int _v1, _v2;
int _state = 0;
Task<int> _await1;
public void Step() {
switch(this._state) {
case 0:
this._v1 = foo();
this._await1 = bar();
// When the async operation completes, it will call this method
this._state = 1;
op.SetContinuation(Step);
case 1:
this._v2 = this._await1.Result; // Get the result of the operation
more(this._v1, this._v2);
}
}
Die belangrike deel is dat dit net gebruik maak van die SetContinuation
metode om te bepaal dat wanneer die operasie is voltooi, dit moet die Step
metode weer 'n beroep (en die metode weet dat dit die tweede bietjie van die oorspronklike kode moet hardloop met behulp van die veld _state
) . Jy kan maklik dink dat die SetContinuation
iets soos btn.Click += Step
, wat heeltemal sou loop op 'n enkele draad sou wees.
Die asynchrone ontwikkeling model in C # is baie naby aan F # asynchrone werkstromen (in werklikheid, dit is in wese dieselfde ding, opsy, weg van 'n paar tegniese besonderhede), en skryf reaktiewe enkel-threaded GUI aansoeke met behulp van async
is nogal 'n interessante gebied - ten minste dink ek so - sien byvoorbeeld hierdie artikel (miskien moet ek 'n C # weergawe nou skryf: -))
Die vertaling is soortgelyk aan iterators (en yield return
) en in waarheid te sê, was dit moontlik om iterators gebruik om asynchrone ontwikkeling in C # vroeër implementeer. Ek het 'n artikel oor wat 'n ruk gelede - en ek dink dit kan nog gee jou 'n paar insig oor hoe die vertaling werk.
Ander wenke
Hoe kan ek 'n operasie uitgevoer in parallel op dieselfde draad?
Jy kan nie. asynchronie is nie "parallelisme" of "concurrency" . Asynchronie kan geïmplementeer word met parallelisme, of dit kan nie wees nie. Dit mag dalk geïmplementeer word deur die opbreek van die werk in klein stukkies, sit elke stuk van die werk op 'n tou, en dan die uitvoering van elke stuk van die werk wanneer die draad gebeur te wees nie enigiets anders te doen.
Ek het 'n hele reeks artikels op my blog oor hoe al hierdie dinge werk; die een direk related op hierdie vraag sal waarskynlik optrek Donderdag van volgende week. Watch
http://blogs.msdn.com/b/ericlippert/archive / tags / asinkroniseer /
vir meer inligting.
Soos ek dit verstaan, wat die async
en await
sleutelwoorde doen, is dat elke keer as 'n async
metode in diens van die await
navraag, sal die samesteller die res van die metode te omskep in 'n voortsetting wat geskeduleer is wanneer die asinkroniseer operasie afgehandel is. Wat dit moontlik maak async
metodes om terug te keer na die oproeper onmiddellik en CV werk wanneer die asinkroniseer deel gedoen.
Volgens die beskikbare vraestelle daar is 'n baie besonderhede word nie, behalwe as ek my nie misgis nie, dit is die kern van dit.
As ek sien dit die doel van die asinkroniseer metodes is baie kode in parallel nie te hardloop, maar om te kap op asinkroniseer metodes in 'n aantal klein stukkies, wat genoem kan word as wat nodig is. Die belangrike punt is dat die samesteller al die komplekse bedrading van verifikasie met behulp van take / voortsettings sal hanteer. Dit verminder nie net kompleksiteit, maar laat asinkroniseer metode min of meer geskryf moet word soos die tradisionele sinchrone kode.