locked
LS Desktop - LoadingRow event and threading RRS feed

  • Question

  • Hi,

    I have the following in the intializeWorkSpace method:

    this.FindControl("grid").ControlAvailable += (s, e) =>
                    {
                        DataGrid grid = e.Control as DataGrid;
                        grid.LoadingRow += (s2, e2) =>
                        {
                            TransactionsGroupee txnGr = e2.Row.DataContext as TransactionsGroupee;
                            if (txnGr != null)
                            {
                                DataGridColumn column = grid.Columns[9];
                                Control rb = column.GetCellContent(e2.Row) as Control;
                                if (rb != null)
                                {
                                    //Dispatchers.Main.BeginInvoke(() =>
                                    //{
                                        rb.IsEnabled = txnGr.Agence1 == SelectedAgence && !txnGr.paye && txnGr.Transactions.Any(z => z.CoursFixe);
                                    //});
                                }
                            }
                        };
                    };

    Whether I use the Dispatchers line or not I get a "not valid in the current thread exception" due to txnGr.Transactions.
    Moreover, the column is a customControl RadioButton but if I try to cast to RadioButton rather than Control, then rb is null.

    Tks for your help.

    François

    Monday, June 24, 2013 11:40 AM

Answers

  • But as I expexted, the IsEnabled line is executed before the Détails thread instruction. I am not very good with mutli threading so I don't know how to wait for the thread to finish. I'll dig a bit on the net while you guys are still asleep ;-)

    When LightSwitch requests long-running data processes (e.g., LINQ in this case) on the logic thread, it uses an async process by default.  .BeginInvoke() replicates this behavior.  You can force LightSwitch's threading to perform this operation synchronously by using .Invoke() instead. 

    this.Details.Dispatcher.Invoke(() =>
          {
             coursFixe = txnGr.Transactions.Any(z => z.CoursFixe);
          });

    Your application may slow down or show the "Please Wait" indicator if you use this method, however.


    • Marked as answer by francois.m Saturday, June 29, 2013 5:34 PM
    Saturday, June 29, 2013 3:55 PM

All replies


  • rb.IsEnabled = txnGr.Agence1 == SelectedAgence && !txnGr.paye && txnGr.Transactions.Any(z => z.CoursFixe);

    This statement would appear to require both the UI thread and the logic thread to correctly execute.  Since SilverLight objects and controls have thread affinity, you'll have to avoid switching threads to assign a value to the SilverLight control.

    First, try putting a breakpoint at this line to see which thread you are actually in, then go to the Immediate Window and query each of the 3 LightSwitch threads using CheckAccess():

    // UI Thread check
    ?Microsoft.LightSwitch.Threading.Dispatchers.Main.CheckAccess()
    // screen logic thread check
    ?this.Details.Dispatcher.CheckAccess()
    // application thread check
    ?this.Application.Details.Dispatcher.CheckAccess()

    I suspect that you are already on the Main Dispatcher when your rb.isEnabled line is executed, based on the error message you mentioned.  The "txnGr.Transactions.Any(z=>z.CoursFixe)" may need to be separated, executed, and assigned on the Details.Dispatcher screen logic thread before the rb.isEnabled can be evaluated.


    Saturday, June 29, 2013 1:45 AM
  • Hi Allen,

    Tks a lot for the reply. Indeed I am in the Main thread. Trying to do what you suggest I wrote the following:

    if (rb != null)
    {
          bool coursFixe = false;
          this.Details.Dispatcher.BeginInvoke(() =>
          {
             coursFixe = txnGr.Transactions.Any(z => z.CoursFixe);
          });
          rb.IsEnabled = txnGr.Agence1 == SelectedAgence && !txnGr.paye && coursFixe;
    }
    But as I expexted, the IsEnabled line is executed before the Détails thread instruction. I am not very good with mutli threading so I don't know how to wait for the thread to finish. I'll dig a bit on the net while you guys are still asleep ;-)
    Saturday, June 29, 2013 6:42 AM
  • I managed to wait for the thread. However, LS get stuck I don' t where trying to execute the txnGr.Transactions instruction whereas if I replace it with something else it's fine. When I add a breakpoint and watch txnGr.Transactions it looks fine. I don't know why it can' t be executed. Here is my new code.

    if (rb != null)
    {
         bool coursFixe = false;
         ManualResetEvent m = new ManualResetEvent(false);
         this.Details.Dispatcher.BeginInvoke(() =>
         {
              try
              {
                    coursFixe = true;// txnGr.Transactions.Any(z =>z.CoursFixe);
              }
              catch (Exception ex)
              {
              }
              finally
              {
                    m.Set();
              }
         });
         m.WaitOne(); 
         rb.IsEnabled = txnGr.Agence1 == SelectedAgence && txnGr.paye && coursFixe;
     }

    Saturday, June 29, 2013 7:20 AM
  • But as I expexted, the IsEnabled line is executed before the Détails thread instruction. I am not very good with mutli threading so I don't know how to wait for the thread to finish. I'll dig a bit on the net while you guys are still asleep ;-)

    When LightSwitch requests long-running data processes (e.g., LINQ in this case) on the logic thread, it uses an async process by default.  .BeginInvoke() replicates this behavior.  You can force LightSwitch's threading to perform this operation synchronously by using .Invoke() instead. 

    this.Details.Dispatcher.Invoke(() =>
          {
             coursFixe = txnGr.Transactions.Any(z => z.CoursFixe);
          });

    Your application may slow down or show the "Please Wait" indicator if you use this method, however.


    • Marked as answer by francois.m Saturday, June 29, 2013 5:34 PM
    Saturday, June 29, 2013 3:55 PM