AMcoder - javascript, python, java, html, php, sql

Ավարտված իրադարձությունների մշակիչ Task.Factory.StartNew(() =› Parallel.ForEach-ի համար

Ես ուզում եմ իմանալ, թե երբ են ավարտվում որոշ զուգահեռ առաջադրանքներ:

Ես օգտագործում եմ այս կոդը՝ կայքէջում 1500-ից մինչև 2000 փոքր WebClient.DownloadString 10 վայրկյան HttpRequest Timeout-ով պատրաստելու համար.

Task.Factory.StartNew(() => 
    Parallel.ForEach<string>(myKeywords, new ParallelOptions 
    { MaxDegreeOfParallelism = 5 }, getKey));

Երբեմն հարցումը ձախողվում է, այնպես որ կան բացառություններ, և գործառույթը երբեք չի ավարտվում, և UI թարմացումը յուրաքանչյուր getKey ֆունկցիայի ներսում երբեմն թվում է, որ երկու անգամ է կանչվում, այնպես որ ես չեմ կարող ճշգրիտ պատկերացում կազմել, թե քանի առաջադրանք է կատարվել: Ես հաշվարկում եմ. UI-ի թարմացման զանգերի քանակը / հիմնաբառերի ընդհանուր քանակը և ստացեք արդյունք 100% -ից մինչև 250%, և ես երբեք չգիտեմ, թե երբ է ավարտվել առաջադրանքը: Ես որոնում եմ շատ SO քննարկումների մեջ, բայց ոչ մեկը ուղղակի մեթոդ կամ մեթոդ չէր, որը համապատասխանում է իմ կարիքներին: Այսպիսով, ես ենթադրում եմ, որ Framework 4.0-ը չի ապահովում Tasks.AllCompleted Event Handler կամ նմանատիպ լուծում:

Պե՞տք է գործարկեմ իմ Parallel.Foreach-ը մեկ այլ շղթայի մեջ՝ իմ UI շղթայի փոխարեն, ապա ավելացնե՞մ այն:

myTasks.WaitAll

[Խմբագրել]

Ժամանակավոր լուծում էր՝ պատճենել տողերի իմ ցուցակը ArrayList-ում, այնուհետև յուրաքանչյուր հարցման սկզբում մեկ առ մեկ հեռացնել յուրաքանչյուր տարր ցանկից: Ամեն անգամ, երբ գործառույթը լավ է աշխատել, թե ոչ, ես գիտեմ, թե երբ են բոլոր տարրերը մշակվել:


  • 1. Դուք ցանկանում եք, թե որ տարրերն են հաջողությամբ ավարտվել, իսկ որոնք՝ ձախողված 2. Դուք ցանկանում եք շարունակական առաջընթաց ստանալ, օրինակ՝ 5%, 10%, ... 100% ....... Եթե Ձեզ անհրաժեշտ է վերը նշվածներից որևէ մեկը, ապա ձեզ հարկավոր է. օգտագործել սեփական համաժամացման մեխանիզմը, որը կարող է դանդաղեցնել ընդհանուր մշակումը (համաժամացման պատճառով)..............Եթե ձեզ միայն անհրաժեշտ է իմանալ, թե որոնք են ձախողվել, ապա ձեր ջերմաստիճանը: լուծումը հարմար է (թեև ոչ էլեգանտը) 26.05.2012
  • Ես երկուսն էլ պահանջեցի, բայց այն աշխատեց առնվազն % նպատակի համար, քանի որ մեկ առ մեկ տարրը երգացանկից հեռացնելը թույլ է տալիս հաշվարկել (ընդհանուր տարրեր - մնացած տարր) / ընդհանուր տարրերը: Համենայն դեպս, եթե ներբեռնումը ձախողվի, ինձնից է կախված, որ այն կարգավորեմ նորից փորձի հանգույցով: 26.05.2012

Պատասխանները:


1

Parallel.ForEach չի տարբերվում մյուս օղակներից, երբ խոսքը վերաբերում է բացառությունների մշակում: Եթե ​​բացառություն արվի, ապա այն պատրաստվում է դադարեցնել օղակի մշակումը: Հավանաբար սա է պատճառը, որ դուք տեսնում եք տոկոսների տարբերություններ (ես ենթադրում եմ, որ դուք կարող եք մշակել հաշվարկը, երբ մշակում եք հանգույցը):

Բացի այդ, ձեզ իրականում պետք չէ Parallel.ForEach քանի որ ասինխրոն զանգերը, որոնք դուք կատարում եք WebClient դասում պատրաստվում է արգելափակել սպասումը IO-ի ավարտը (ցանցի պատասխանները), դրանք հաշվողականորեն կապված չեն (Parallel.ForEach շատ ավելի լավ է, երբ դուք հաշվողականորեն կապված եք):

Այսպիսով, դուք պետք է նախ թարգմանեք ձեր զանգերը WebClient՝ Task<TResult> օգտագործելու համար: իրադարձությունների վրա հիմնված ասինխրոն օրինակը թարգմանվում է առաջադրանքի վրա հիմնված ասինխրոն օրինաչափություն պարզ է TaskCompletionSource<TResult> դաս:

Ենթադրելով, որ դուք ունեք Uri օրինակների հաջորդականություն, որոնք արտադրվում են որպես getKey-ին կատարած ձեր զանգերի արդյունքում դուք կարող եք ստեղծել գործառույթ՝ դա անելու համար.

static Task<String> DownloadStringAsync(Uri uri)
{
    // Create a WebClient
    var wc = new WebClient();

    // Set up your web client.

    // Create the TaskCompletionSource.
    var tcs = new TaskCompletionSource<string>();

    // Set the event handler on the web client.
    wc.DownloadStringCompleted += (s, e) => {
        // Dispose of the WebClient when done.
        using (wc)
        {
            // Set the task completion source based on the
            // event.
            if (e.Cancelled)
            {
                // Set cancellation.
                tcs.SetCancelled();
                return;
            }

            // Exception?
            if (e.Error != null)
            { 
                // Set exception.
                tcs.SetException(e.Error);
                return;
            }

            // Set result.
            tcs.SetResult(e.Result);
        };

    // Return the task.
    return tcs.Task;
};

Նկատի ունեցեք, որ վերը նշվածը կարող է օպտիմիզացվել մեկ WebClient-ն օգտագործելու համար, որը մնում է ձեզ համար որպես վարժություն (ենթադրելով, որ ձեր թեստերը ցույց են տալիս, որ դրա կարիքն ունեք):

Այնտեղից կարող եք ստանալ Task<string>-ի հաջորդականությունը.

// Gotten from myKeywords
IEnumerable<Uri> uris = ...;

// The tasks.
Task<string>[] tasks = uris.Select(DownloadStringAsync).ToArray();

Նկատի ունեցեք, որ դուք պետք է զանգահարեք ToArray ընդլայնման եղանակով որպեսզի առաջադրանքները սկսեն գործել: Սա նախատեսված է հետաձգված կատարումը շրջանցելու համար . Պետք չէ զանգահարել ToArrayին, բայց դուք պետք է զանգահարեք մի բան, որը կթվարկի ամբողջ ցանկը և կառաջարկի առաջադրանքների գործարկումը:

Երբ դուք ունեք այս Task<string> օրինակները, կարող եք սպասել, որ դրանք բոլորը ավարտվեն՝ զանգահարելով ContinueWhenAll<TAntecedentResult> մեթոդ TaskFactory դասում , այսպես.

Task.Factory.ContinueWhenAll(tasks, a => { }).Wait();

Երբ դա արվի, դուք կարող եք շրջել tasks զանգվածի միջով և դիտել Exception և/կամ Result հատկություններ ստուգելու համար, թե որն է բացառությունը կամ արդյունքը:

Եթե ​​դուք թարմացնում եք օգտատիրոջ միջերեսը, ապա պետք է ուշադրություն դարձնեք զանգի գաղտնալսմանը Հաշվառելի: Ընտրեք, մասնավորապես, դուք պետք է զանգահարեք ContinueWith<TNewResult> մեթոդը: the Task<TResult> գործողություն կատարելու համար երբ ներբեռնումն ավարտված է, օրինակ՝

// The tasks.
Task<string>[] tasks = uris.
    Select(DownloadStringAsync).
    // Select receives a Task<T> here, continue that.
    Select(t => t.ContinueWith(t2 => {
        // Do something here: 
        //   - increment a count
        //   - fire an event
        //   - update the UI
        // Note that you have to take care of synchronization here, so
        // make sure to synchronize access to a count, or serialize calls
        // to the UI thread appropriately with a SynchronizationContext.
        ...

        // Return the result, this ensures that you'll have a Task<string>
        // waiting.
        return t2;
    })).
    ToArray();

Սա թույլ կտա ձեզ թարմացնել բաները, երբ դրանք տեղի են ունենում: Նկատի ունեցեք, որ վերը նշված դեպքում, եթե նորից զանգահարեք Select-ին, գուցե ցանկանաք ստուգել t2-ի վիճակը և ակտիվացնել որոշ այլ իրադարձություններ՝ կախված նրանից, թե ինչպիսին է ձեր սխալների հետ աշխատելու մեխանիզմը:

09.10.2012
Նոր նյութեր

Օգտագործելով Fetch Vs Axios.Js-ը՝ HTTP հարցումներ կատարելու համար
JavaScript-ը կարող է ցանցային հարցումներ ուղարկել սերվեր և բեռնել նոր տեղեկատվություն, երբ դա անհրաժեշտ լինի: Օրինակ, մենք կարող ենք օգտագործել ցանցային հարցումը պատվեր ներկայացնելու,..

Տիրապետել հանգստության արվեստին. մշակողի ուղեցույց՝ ճնշման տակ ծաղկելու համար
Տիրապետել հանգստության արվեստին. մշակողի ուղեցույց՝ ճնշման տակ ծաղկելու համար Ինչպե՞ս հանգստացնել ձեր միտքը և աշխատեցնել ձեր պրոցեսորը: Ինչպես մնալ հանգիստ և զարգանալ ճնշման տակ...

Մեքենայի ուսուցում բանկային և ֆինանսների ոլորտում
Բարդ, խելացի անվտանգության համակարգերը և հաճախորդների սպասարկման պարզեցված ծառայությունները բիզնեսի հաջողության բանալին են: Ֆինանսական հաստատությունները, մասնավորապես, պետք է առաջ մնան կորի..

Ես AI-ին հարցրի կյանքի իմաստը, այն ինչ ասում էր, ցնցող էր:
Այն պահից ի վեր, երբ ես իմացա Արհեստական ​​ինտելեկտի մասին, ես հիացած էի այն բանով, թե ինչպես է այն կարողանում հասկանալ մարդկային նորմալ տեքստը, և այն կարող է առաջացնել իր սեփական արձագանքը դրա..

Ինչպես սովորել կոդավորումը Python-ում վագրի պես:
Սովորելու համար ծրագրավորման նոր լեզու ընտրելը բարդ է: Անկախ նրանից, թե դուք սկսնակ եք, թե առաջադեմ, դա օգնում է իմանալ, թե ինչ թեմաներ պետք է սովորել: Ծրագրավորման լեզվի հիմունքները, դրա..

C++-ի օրական բիթ(ե) | Ամենաերկար պալինդրոմային ենթաշարը
C++ #198-ի ամենօրյա բիթ(ե), Ընդհանուր հարցազրույցի խնդիր. Ամենաերկար պալինդրոմային ենթատող: Այսօր մենք կանդրադառնանք հարցազրույցի ընդհանուր խնդրին. Ամենաերկար palindromic substring...

Kydavra ICAReducer՝ ձեր տվյալների ծավալայինությունը նվազեցնելու համար
Ի՞նչ է ICAReducer-ը: ICAReducer-ն աշխատում է հետևյալ կերպ. այն նվազեցնում է նրանց միջև բարձր փոխկապակցված հատկանիշները մինչև մեկ սյունակ: Բավականին նման է PCAreducer-ին, չնայած այն..