Bespeur dat 'n ThreadPool-werkitem voltooi is/wag vir voltooiing
-
03-07-2019 - |
Vra
Om watter rede ook al, ThreadPool
se QueueWorkItem
gee nie terug nie IAsyncResult
of 'n ander handvatsel aan die werkitem, wat sal toelaat om te wag totdat dit voltooi is.Daar is RegisterWait...
metodes, maar jy moet 'n slaag WaitHandle
en dit is duur om dit te skep (sien IAsyncResult
dokumentasie, wat jou aanraai om die skep van 'n WaitHandle
totdat dit versoek word).Die Task Parallel Library sal hierdie gebrek regstel, maar daar is 'n lang wag voordat dit beskikbaar is.So, is daar enige probleme met hierdie ontwerp:
public class Concurrent<T> {
private ManualResetEvent _resetEvent;
private T _result;
public Concurrent(Func<T> f) {
ThreadPool.QueueUserWorkItem(_ => {
_result = f();
if (_resetEvent != null)
_resetEvent.Set();
});
}
public WaitHandle WaitHandle {
get {
if (_resetEvent == null)
_resetEvent = new ManualResetEvent(_result != null);
return _resetEvent;
}
...
EDIT:Ek het gevra a opvolgvraag oor die bekommernisse wat ontstaan wanneer asinc-afgevaardigdes in plaas van die ThreadPool gebruik word.
Oplossing
Wel, jy het 'n wedloop-toestand tussen die haal van die WaitHandle en die instelling daarvan.Wil jy regtig hê die beller moet vir ewig wag as hulle toevallig 'n klein bietjie laat is?
Jy moet waarskynlik 'n gepaste sluiting doen en 'n "Ek is klaar" vlag hou sodat as jy doen skep die WaitHandle nadat dit klaar is, stel jy dit voor jy dit terugstuur.
Ek sou ook persoonlik 'n statiese fabrieksmetode skryf eerder as om net 'n openbare konstruktor te gebruik - of dit 'n "skep en dan eksplisiet begin" patroon.Om die werkitem in die konstruktor in tou te staan, voel vir my vreemd.
Ander wenke
Hoekom gebruik jy nie 'n asynchrone afgevaardigde nie, soos hier gedemonstreer:
http://msdn.microsoft.com/en-us/library/h80ttd5f.aspx
Dit sou Concurrent verouderd maak, nie waar nie?