views:

89

answers:

1

let's say we are using IValueConverter to format a GridView cell background color depending on its value.

now let's say that value is calculated on a separate thread, after adding the item to the collection.

        var args = GetInput();
        if (ValidateArgs(args))
        {
            if (args.Rate.HasValue)
                ThreadPool.QueueUserWorkItem(o => YieldCalculator.CalcPrice(args));
            if (args.Price.HasValue)
                ThreadPool.QueueUserWorkItem(o => YieldCalculator.CalcYield(args));
            _argsCollection.Add(args);
        }

each method will calculate a field, and update args with its result.

_argsCollection is a ObservableCollection, and it will show the new item right away + run the converter, but if the value is not yet calculated, converter will not be able to do its work as it doesn't have all the information.

once the value is calculated, and set, INotifyPropertyChanged will signal UI, and the calculated value will show up in the grid, however the Converter has already run, and it doesn't appear to be re-triggered.

one way around this is to not add the item to the collection until the calculation is done. not crazy about this because the method outsourced to another thread has no knowledge of observable collection, and passing that along would not be good design IMO, as it makes it a tighter coupled solution.

another way is to call Items.Refresh on the grid (but this will run converter on all visible rows)

also if this was framework 4.0 i could use something like ParallelTaskLibrary and WaitAll and add the item only after all threads were done.. but on 3.5 so need a less sexy solution.

any other ideas?

A: 

by reading your lines "also if this was framework 4.0 i could use something like ParallelTaskLibrary and WaitAll and add the item only after all threads were done.. but on 3.5 so need a less sexy solution." and if i understood your problem than

i think your problem lies in the fact that you are not able to control Threadpool's thread synchronization.

there is a well defined Asynchronous pattern written by the Microsoft search for that, you can pass AsyncDelegate which will call your EndInvoke type of function which will again refresh your bindings.

2- Another way around use explicit threads + ManualResetEvents to control your problem.

saurabh