2015-05-19 1 views
2

Если у меня есть несколько асинхронных абоненты, которые ожидают обновление данных, когда я должен предпочесть один метод над другим в этом фрагменте:Событие против RegisterWaitForSingleObject для нескольких асинхронных потребителей данных

public delegate void NewDataHandler(int data); 

public class DataSource { 
    public event NewDataHandler OnNewData; 
    public AutoResetEvent are = new AutoResetEvent(false); 


    public void AddData(int i) { 
     OnNewDataInvoke(i); 
    } 

    private void OnNewDataInvoke(int data) { 
     OnNewData?.Invoke(data); 
     are.Set(); 
    } 

    public Task WaitEventAsync() { 
     var tcs = new TaskCompletionSource<bool>(); 
     var subscribtion = (NewDataHandler)null; 
     subscribtion = (i) => { 
      tcs.TrySetResult(true); // note that i ignored here, but could send actual data 
      OnNewData -= subscribtion; 
     }; 
     OnNewData += subscribtion; 
     return tcs.Task; 
    } 

    public Task WaitAREAsync() { 
     var tcs = new TaskCompletionSource<bool>(); 
     var rwh = ThreadPool.RegisterWaitForSingleObject(are, 
      delegate { tcs.TrySetResult(true); }, null, -1, true); 
     var t = tcs.Task; 
     t.ContinueWith(_ => rwh.Unregister(null)); 
     return t; 
    } 
} 

Событие является более распространенным и позволяют захватывать полезную нагрузку данных, а не только сигнал о том, что данные были обновлены. Есть ли какая-либо польза от RWFSO?

(Rx будет простым ответом для многих абонентов, но я пытаюсь моделировать тянуть основанный асинхронный поток данных)

+1

Вы можете использовать 'TaskCompletionSource ' для возврата данных из ожидаемого результата в качестве полезной нагрузки. –

+0

@YuvalItzchakov yep, но только событие позволит захватить данные. Есть ли причина использовать RWFSO в этом контексте? –

+0

Я не вижу большой разницы. Один из них основан на событиях, один из которых основан на обратном вызове (которые почти одинаковы). Какой бы вы ни находили подходящим. –

ответ

1

RegisterWaitForSingleObject в сочетании с событием является более дорогим и сложным в использовании. Я не могу представить, почему сейчас это нужно.

TaskCompletionSource можно удвоить как событие, которое является хорошим образцом. Ясно, что это «событие» можно установить только один раз. TaskCompletionSource хорошо работает с остальной частью TPL (await и комбинаторами задач).

+0

В конце концов, останется только событие или RWFSO + ARE, оба используют TCS. Вопрос состоял в том, какой из них сохранить и который удалить: 'WaitEventAsync' или' WaitAREAsync', они не используются в какой-либо комбинации. Вот только пример того, как использовать оба. –

+0

Keep WaitEventAsync. Я думал, что я ясно дал понять, что нет никаких преимуществ WaitAREAsync. Очевидно нет. – usr

+0

Можем ли мы сказать тогда, что RWFSO полезен только тогда, когда шаблон события невозможен, например. неуправляемый дескриптор ожидания? –

Смежные вопросы