Re[2]: [F#] вызов подписчиков на событие асинхронно
От: cadet354 Россия
Дата: 30.09.10 12:28
Оценка:
Здравствуйте, desco, Вы писали:



D>стандартный Event<_, _> такого точно не сумеет, насчет Rx не уверен, но тоже есть сомнения. IMO проще сделать свой вариант Event, навроде такого (функционал для поддержки работы из нескольких потоков добавлять самому по вкусу)

спасибо, не хотел свой велосипед писать, думал есть что стандартное.
D>
D>    type Invoker<'D, 'A> = delegate of 'D * obj * 'A -> unit
D>    type Event<'D, 'A when 'D :> Delegate and 'D : delegate<'A, unit> and 'D : null>() =
D>        static let invoker = Delegate.CreateDelegate(typeof<Invoker<'D, 'A>>, typeof<'D>.GetMethod("Invoke")) :?> Invoker<'D, 'A>
            
D>        let mutable multicast : 'D = null    
     
D>        member x.Trigger(sender:obj,args: 'A) =
D>            match multicast with
D>            | null -> ()
D>            | d -> invoker.Invoke(d, sender, args) // DelegateEvent uses: d.DynamicInvoke(args) |> ignore

D>        member x.TriggerAsync(sender : obj, args : 'A) = 
D>            let delegates = 
D>                match multicast with
D>                | null -> Array.empty
D>                | d -> d.GetInvocationList()
D>            delegates
D>                |> Seq.map (fun d -> async { invoker.Invoke(d :?> _, sender, args) } )
D>                |> Async.Parallel
D>                |> Async.Ignore
 
D>        member x.Publish =
D>            { new IDelegateEvent<'D> with
D>                member x.AddHandler(d) =
D>                    multicast <- System.Delegate.Combine(multicast, d) :?> 'D
D>                member x.RemoveHandler(d) =
D>                    multicast <- System.Delegate.Remove(multicast, d)  :?> 'D }
D>


D>такая реализация будет как минимум быстрее стандартной, которая внутри для вызова делегата использует Delegate.DynamicInvoke

я посмотрел стандартную имплементацию, со фразами workaround bug WP7
... << RSDN@Home 1.2.0 alpha 4 rev. 1270>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.