SORU
5 Temmuz 2013, Cuma


Uygulama yinelenebilir bir bloğunun tamamlanması doğru

Teaserçocuklar, bu soru politikasını yeniden uygulamak hakkında değil. VUK veri akışı bloğu hakkında doğru tamamlanması.

Bu soru genelde benim önceki soru Retry policy within ITargetBlock bir devamıdır. Bu sorunun cevabı @TransformBlock (kaynağı) ve TransformManyBlock (hedef) kullanan svick akıllı çözüm oldu. Tek sorun, Sol bir bu bloğu tamamlamak içindoğru yolu: tüm deneme ilk tamamlanması için bekleyin ve hedef blok tamamlayın. (Sadece bir parçasında, olmayan iş parçacığı için güvenli retries bir set için çok fazla önem verme) ile sona erdi:

var retries = new HashSet<RetryingMessage<TInput>>();

TransformManyBlock<RetryableMessage<TInput>, TOutput> target = null;
target = new TransformManyBlock<RetryableMessage<TInput>, TOutput>(
    async message =>
    {
        try
        {
            var result = new[] { await transform(message.Data) };
            retries.Remove(message);
            return result;
        }
        catch (Exception ex)
        {
            message.Exceptions.Add(ex);
            if (message.RetriesRemaining == 0)
            {
                if (failureHandler != null)
                    failureHandler(message.Exceptions);

                retries.Remove(message);
            }
            else
            {
                retries.Add(message);
                message.RetriesRemaining--;

                Task.Delay(retryDelay)
                    .ContinueWith(_ => target.Post(message));
            }
            return null;
        }
    }, dataflowBlockOptions);

source.LinkTo(target);

source.Completion.ContinueWith(async _ =>
{
    while (target.InputCount > 0 || retries.Any())
        await Task.Delay(100);

    target.Complete();
});

Fikri yoklama çeşit gerçekleştirmek ve hala işlenmek üzere bekleyen iletiler olup olmadığını doğrulamak için yeniden deneniyor gerektiren bir mesaj var. Ama bu çözüm yoklama fikri hoşuma gitmiyor.

Evet, ben saklanması mantığı ekleme/çıkarma deneme ayrı bir sınıf ve hatta örneğin bazı eylemleri gerçekleştirmek için denemeleri olur boş, ama nasıl davranılması target.InputCount > 0 durum? Blok için bekleyen mesaj varsa denilen gibi bir geri arama yok, hayır, küçük bir gecikme ile bir döngü içinde target.ItemCount doğrulama sadece bir seçenek gibi görünüyor.

Herkes akıllı bir şekilde bunu başarmak için biliyor mu?

CEVAP
7 EKİM 2013, PAZARTESİ


Belki ManualResetEvent sizin için hile yapabilir.

TransformManyBlock ortak bir özellik ekleyin

private ManualResetEvent _signal  = new ManualResetEvent(false);
public ManualResetEvent Signal { get { return _signal; } }

Ve işte burada:

var retries = new HashSet<RetryingMessage<TInput>>();

TransformManyBlock<RetryableMessage<TInput>, TOutput> target = null;
target = new TransformManyBlock<RetryableMessage<TInput>, TOutput>(
    async message =>
    {
        try
        {
            var result = new[] { await transform(message.Data) };
            retries.Remove(message);

            // Sets the state of the event to signaled, allowing one or more waiting threads to proceed
            if(!retries.Any()) Signal.Set(); 
            return result;
        }
        catch (Exception ex)
        {
            message.Exceptions.Add(ex);
            if (message.RetriesRemaining == 0)
            {
                if (failureHandler != null)
                    failureHandler(message.Exceptions);

                retries.Remove(message);

                // Sets the state of the event to signaled, allowing one or more waiting threads to proceed
                if(!retries.Any()) Signal.Set(); 
            }
            else
            {
                retries.Add(message);
                message.RetriesRemaining--;

                Task.Delay(retryDelay)
                    .ContinueWith(_ => target.Post(message));
            }
            return null;
        }
    }, dataflowBlockOptions);

source.LinkTo(target);

source.Completion.ContinueWith(async _ =>
{
    //Blocks the current thread until the current WaitHandle receives a signal.
    target.Signal.WaitOne();

    target.Complete();
});

target.InputCount set nerede emin değilim. Yerde target.InputCount değiştirmek çok aşağıdaki kodu ekleyebilirsiniz:

if(InputCount == 0)  Signal.Set();

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Associated Press

    Associated P

    18 EYLÜL 2006
  • Eric Enge

    Eric Enge

    2 Kasım 2009
  • kev5124

    kev5124

    9 Kasım 2008