locked
Can I dynamically generate the list of paramiters for Parallel.Invoke()? Please reply me second time. RRS feed

  • Question

  • Hi!

    I have a following class:

    class MyClass
    {
       public Int32 A{get; set;}
       public Int32 B{get; set;}
    }

    There is an Observable Collection:

    private ObservableCollection<MyClass
    > myColl = new ObservableCollection<MyClass
    >();

    I do the following:

    MyClass mc_1 = new MyClass();
    MyClass mc_2 = new MyClass();

    Then I do:

    public ObservableCollection MyColl
    {
       get {return myColl;}
    }
    
    var actions = new List<Action>();
    
    for(int i == 0; i < MyColl.Count; i++)
    {
        Int32 inx = i;
        actions.Add(()=>
        {
            MyClass mc = MyColl[inx];
            mc.A = 5;
            mc.B = 10;
        });
    }
    
    if (actions.Count > 0)
           Parallel.Invoke(actions.ToArray());

    Is the call of Parallel.Invoke() correct here?


    • Edited by TownSparrow Tuesday, July 16, 2013 2:19 PM corrected
    Monday, July 15, 2013 5:41 PM

Answers

All replies

  • That will work fine - though it'd be simpler to use PLINQ.  With PLINQ, you can avoid creating the actions and the for loop entirely - once you have the collection, just do:

    MyColl.AsParallel().ForAll(mc => 
    {
        mc.A = 5;
        mc.B = 10;
    });


    Reed Copsey, Jr. - http://reedcopsey.com - If a post answers your question, please click Mark As Answer on that post. If you find a post helpful, please click Vote as Helpful.

    • Marked as answer by TownSparrow Tuesday, July 16, 2013 5:43 PM
    Monday, July 15, 2013 5:47 PM
    Moderator
  • Thank you. I bag your pardon that I've deviated from subject of my question but I have the following situation. I'm developing now an application for trading on stock exchange. I build my application according to MVVM pattern. Thereby I have two view model classes in the application: FuturesTradeViewModel and MainWindowViewModel. Below I present them conceptually not wholly.

    This is FuturesTradeViewModel class:

    class FuturesTradeViewModel
    {
       #region Fields
       /// <summary>
       /// The flag of exceeding of threshold point.
       /// </summary>
       _f_ThresholdExceeded = false;
       #endregion
    
       #region Properties
       /// <summary>
       /// Minimum value of dispersion.
       /// </summary>
       public Decimal MinDispersion { get; set; }
       /// <summary>
       /// Some threshold point for dispersion.
       /// </summary>
       public Decimal ThresholdPoint {get; set;}
       /// <summary>
       /// The flag of exceeding of threshold point.
       /// </summary>
       public Boolean F_ThresholdExceeded
       {
           get { return _f_ThresholdExceeded; }
           set { _f_ThresholdExceeded = value; }
       }
    
    }

    FuturesTradeViewModel reprecents trading of one futures (traded instrument). Since in the application there are more then one futures  per time can be traded so there are some FuturesTradeViewModel instances in the application and each one of them represents workspace for trading of one futures. There is one instance of MainWindowViewModel which contains an ObservableCollection of FuturesTradeViewModel instances. This is MainWindowViewModel class:

    /// <summary>
    /// MainWindowViewModel class is the data context of
    /// application main window.
    /// </summary>
    class MainWindowViewModel
    {
        #region Fields
        /// <summary>
        /// The collection of workspaces (futures trade
        /// instances), displaying in application main window.
        /// </summary>
        private ObservableCollection<FuturesTradeViewModel> _workspaces;
        #endregion
    
        #region Properties
        /// <summary>
        /// The collection of workspaces.
        /// </summary>
        public observableCollection Workspaces
        {
            get { rerturn _workspaces; }
        }
        #endregion
    
        #region Commands
        /// <summary>
        /// Return a command executing connection to, 
        /// stock exchange
        /// </summary>
        public ICommand ConnectToStockExchangeCommand
        {
            get
            {
              . . . . . . . . . . . . . . . . . .
                this.ConnectToStockExchange()
              . . . . . . . . . . . . . . . . . .
                return _connectToStockExchangeCommand;
            }
        }
        #endregion
    
        #region Methods
        /// <summary>
        /// Run TPL task to connect to stock exchange
        /// and receive market data.
        /// </summary>
        private void ConnectToStockExchange()
        {
            Task tskConnectAndReceiveMarketData = Task.Factory.StartNew(ConnectAndReceiveMarketData,
                    TaskCreationOptions.LongRunning);
        }
    
        /// <summary>
        /// Task method.
        /// </summary>
        private void ConnectAndReceiveMarketData()
        {
            // Connector to stock exchange server.
            Connection conn = new Connection();
            // The loop to check connector.
            while(true)
            {
                // Get connector status:
                State state = conn.State;
                if (state == State.Active)
                {
                    if (Workspaces.Count > 0)
                    {
                        Task tskThresholdExceeding = Task.Factory.StartNew(CheckThresholdExceeding);
                    }
                }
            }
        }
    
        /// <summary>
        /// Check threshold point exceeding.
        /// </summary>
        private void CheckThresholdExceeding()
        {
            Workspaces.AsParallel().ForAll(futuresTrade => 
            {
                // Get new value of dispersion.
                Decimal newDispersion = this.GetNewDispersion();
                if(newDispersion - futuresTrade.MinDispersion) > futuresTrade.ThresholdPoint)
                {
                    futuresTrade.F_ThresholdExceeded = true;
                    futuresTrade.MinDispersion = newDispersion;
                    SendOrderToStockExchange();
                }
            });
        }
    
        void SendOrderToStockExchange()
        {
            // Some actions . . . .
        }
        #endregion
    }

    (The command ConnectToStockExchangeCommand is executed with button click in the view part of the application.) Then. I call tskThresholdExceeding TPL task from ConnectAndReceiveMarketData method because the connector status checking loop must run uninterruptedly without delays to processing other operations in the application (particularly to check threshold point exceeding). So CheckThresholdExceeding() method must execute in parallel to ConnectAndReceiveMarketData(). Please reply me: Will framework shown above work correctly? Especially I'm interested in starting tskThresholdExceeding from ConnectAndReceiveMarketData and working of CheckThresholdExceeding. Please reply me.

    Yours sincerely  Eugene.






    • Edited by TownSparrow Tuesday, July 16, 2013 2:33 PM corrected
    Tuesday, July 16, 2013 7:38 AM
  • First, for use as a ViewModel, you'll need to implement INotifyPropertyChanged on all of your properties.

    Otherwise, things should, in general, work.  WPF will automatically marshal the threading calls for the primitive actions across correctly, so that shouldn't be an issue in your bindings.


    Reed Copsey, Jr. - http://reedcopsey.com - If a post answers your question, please click Mark As Answer on that post. If you find a post helpful, please click Vote as Helpful.

    Tuesday, July 16, 2013 4:48 PM
    Moderator
  • Thank you very much. Concerning INotifyPropertyChanged interface - I use it in my application.
    Tuesday, July 16, 2013 5:42 PM