Posts Tagged Threading

C# Silverlight WCF: Thread Safe Multiple Async Call Strategy With Final Operation To Join Data.

Seven Pointing Arrows ending at different points except one arror leaping of the page to show the final Async call.This article describes one way to handle asynchronous or async calls in .Net 3.5 or .Net 4.0 when using WCF in Silverlight in C#. The goal is to have a final operation wait for all the calls to finish so to combine all the data gathered, all in a thread safe way. A secondary goal is to minimize the consumer code required to perform this operation from what is currently available in straight WCF async calls.

This article has a short shelf life because after .Net 4 (see What’s Next in C#? Get Ready for Async!) one will use the built in Asynchrony methodology developed. Until that time if one is using any version of Silverlight and WCF then this article describes how to handle those multiple async calls and join the data in a final method call.

Final Result Example

Before delving into the solution, here is how the consumer will use the methodology. Below a user is getting account information of user requests, departments and accounts to join all the data on the view model in the final method for display on a Silverlight page. Thesee operations as shown are setup when the view model class (MyViewModel) is created and no blocking occurs keeping UI thread clear.

public MyViewModel()
{
    DataContext = new MyServiceClient();

    FinalAsync(CombineDataAndDisplay); // When all the data is retrieved, do this method to combine the data From the 3 async callls below

    // Provide the operation as a lambda (could be a method call) to assign data to our target backing store property
    // and if all has gone well (no errors in other async calls) and it is the final completing operation. Do the final
    // Processing call automatically.
    DataContext.GetUserRequestsCompleted   += (s, e) => { AssignResultCheckforAllAsyncsDone(e, e.Result, ref _UserRequests, "Acquisition failure for User Requests");};
    DataContext.GetAccountsCompleted       += (s, e) => { AssignResultCheckforAllAsyncsDone(e, e.Result, ref _Accounts, "Acquisition Failure for Accounts"); };
    DataContext.GetDepartments             += (s, e) => { AssignResultCheckforAllAsyncsDone(e, e.Result, ref _Departments, "Failed to get Department Info."); };   

    // Start the Async processes 
    MultipleAsyncRun(DataContext.GetUserRequestsAsync);
    MultipleAsyncRun(DataContext.GetAccountsAsync);
    MultipleAsyncRun(DataContext.GetDepartmentsAsync);

    // Exit out and return the UI thread to the user operations.
}

// Once all the data is done, combine and assign into our
// PagedCollectionView property for display on the screen.
public void CombineDataAndDisplay()
{
    // Combine missing data on the calls
   _UserRequests.ToList()
                .ForEach(ur =>
                {
                ur.BillingName     = _Accounts.First(ac => ur.AccountID == ac.AccountID).Name;
                ur.DepartmentName  = _Departments.First(dp => dp.DepartmentID == ur.DepartmentID).Name;
                });


    UserRequests = new PagedCollectionView( _UserRequests);
    UserRequests.GroupDescriptions.Add(new PropertyGroupDescription("DepartmentName"));

}
Explanation
Line  5: The final async call is where this process specifies a method to use after all async calls are completed. On line 24 of the example is our final operation method to do that which is reported to FinalAsync.
Line 11-13: Just like the normal async process we subscribe to the anync handler but we handle it in a anonymous lambda.
Line 11-13: AssignResultCheckForAllAsyncsDone method will check the result returned, code show later in the article. All one needs to know now is that the respective _UserRequests, _Accounts and _Departments, all backing store variables (not properties) will be loaded with the data if the result information ( e ) operation contains no errors. This method does all the heavy lifiting by checking error state, loading the data variable, decrementing the async count and firing off the final method if all asynchronous operations are completed.
Line 16-18: Just like the normal WCF async process we must launch the asnc calls and these statements do just that. We supply the method to be launched inside the MulipleAsync method.
Line 24: Here is our final method to be executed once the asynchrony process is complete. This method combines all the async data internally into the _UserRequest object at which it becomes complete and can be used.
Line 34: Finally a paged collection view is created from our data to be bound to Silverlight Xaml items which is our end result.
24-37: Note: The section below has a variable entitled AsyncErrors. The above example did not check that for null or an error situation. I have left out the check of AsyncErrors for brevity of the example. See the last section for an example of proper error handling.

Multiple Async Methodology Plumbing

Below is what will needed to be brought into your View Model, or placed on your page if not using MVVM. This is where the .Net thread safe Silverlight asynchronous operations will occur.

// Lock Objects 0 for false, 1 for true.
private int AsyncErrorResource = 0;
private int AsyncFinal = 0;

private List<Exception> AsyncErrors;  // If not null errors have been encountered.

private int PendingAsyncOperations; // Holds the counted total of ongoing async operations. Zero means do users final operation.

private Action FinalOperation;      // The user's final operation.

public void MultipleAsyncRun(Action Operation)
{
    Interlocked.Increment(ref PendingAsyncOperations);
    Operation();
}

public void FinalAsync(Action method)
{
    FinalOperation = method;
}

public void AssignResultCheckforAllAsyncsDone<T>(AsyncCompletedEventArgs ea, T receivedData, ref T assignTo, string ErrorMessage)
   where T : class
{
    bool valid = !((ea.Error != null) || (receivedData == null));

    if (valid == false)
    {
        if (0 == Interlocked.Exchange(ref AsyncErrorResource, 1))
        {
            if (AsyncErrors == null)
                AsyncErrors = new List<Exception>();

            AsyncErrors.Add(ea.Error);

            //Release the lock
            Interlocked.Exchange(ref AsyncErrorResource, 0);
        }
    }
    else
    {
        assignTo = receivedData;
    }

    Interlocked.Decrement(ref PendingAsyncOperations);
    if (PendingAsyncOperations == 0)
    {
        if (0 == Interlocked.Exchange(ref AsyncFinal, 1))
        {
            FinalOperation();
        }

        Interlocked.Exchange(ref AsyncFinal, 0);
        Interlocked.Decrement(ref PendingAsyncOperations); // Move to -1
    }
}
Explanation
Line  2/3: These variables are used as a lock targets for thread safety. Value zero means its open and a value of 1 means a lock is in place.
Line  5: Any errors encountered are placed into AsyncErrors. The final operation must check this variable. If it is not null errors have occurred and data is incomplete see the final section of this article on how to handle errors.
Line 7: This variable will hold the running total async operations. Once it gets to zero the final operation will be executed.
Line 11: This method counts and stores our async operations as they come in and launches the async method as well.
Line 13: This process uses the Interlocked class found in the System.Threading namespace. To quote Microsoft, “Provides atomic operations for variables that are shared by multiple threads. “. We simply count up the PendingAsyncOperations variable. Later when the operations complete this will be decremented.
Line 18: This method is called by the consumer so we know what method to launch when all async operations have completed. We assign the method to a holder variable as found on line 9.
Line 22: This method will take in the event arguments and check if there is a problem. It will store the error if there is one and also decrement our count. If our count hits zero it will launch the users final operation.
25-39: Checking errors reported by the async call. If there are any we log them and do not assign the variable. Note whether an error exists or not the operation continues below where the final operation is checked for and executed. Its up to the final operation to check if errors exists and handle them appropriately.
Line 42: If the event reports a success this is where we assign the value to the passed in reference to the template T assignTo. If one doesn’t use a variable for assignTo reference an exception will be generated on this line. See the following section as to why. 
Line 46: We safely decrement our operations count variable. Zero means we are done!
Line 47-57: Here is where we execute the final operation when the count is zero. Note there is an extra lock if operations unlikely hit a zero at the same time. The extra lock ensures only one will execute the final method.

That is it, simply use the above code and you can have all your operations work done asynchronously. Smile Now for the disclaimers…

Why Can’t Properties be Used by AssignResultCheckforAllAsyncsDone?

We must use direct variables like in our example

private ObservableCollection<UserRequestDTO> _UserRequests;
private ObservableCollection<Account> _Accounts;
private ObservableCollection<Department> _Deparments;

// Not Private ObservableCollection<Department> _Departments { get; set; }

If one used a property this exception is thrown.

A property, indexer or dynamic member access may not be passed as an out or ref parameter

That is because we are using the generic method AssignResultCheckforAllAsyncsDone to assign a value, and that assignment has to have an exact object instance for the template (T) object and not a Property to assign the value. If your end result is in a property, simply assign it from the variable to the property in the final async call.

Handling Errors

Simply check the error variable if it is not null it has encountered errors.

if (AsyncErrors != null)
{
    MessageBox.Show("Errors: " + string.Join(string.Format("{0}{0}", Environment.NewLine), AsyncErrors.Select(ex => ex.Message)));
}
else
{
    // Success Handle accordingly.
}
Share

Tags: , , , ,

C# WPF: Linq Fails in BackgroundWorker DoWork Event

iStock_000010874966XSmall I write this because if I ran into this, someone else will. Now first off it wasn’t Linq that failed, but it looked like it and here is my story of failure I found in a WPF background worker threading code which can happen in other areas as well.

The perennial advice to all people in the MSDN forums as well as others is never, never, never  write to a GUI control in a thread or the BackgroundWorker’s do work event. All GUI work must be done on a the GUI. I very well knew that…but the reverse (don’t read from a GUI in a different thread)  is also true and that bit me. Let me explain.

Anecdotal Evidence

Imagine my surprise when I created a WPF project at a new job and started getting this exception in the DoWork code of my BackgroundWorker when the first use of a Linq query’s delayed execution point was accessed :

The calling thread cannot access this object because a different thread owns it.

The code threw an exception, on line 16 below, where I was loading data from after the Linq call.  I began to think, does this have something to do with the Linq DataContext?

void bcLoad_DoWork(object sender, DoWorkEventArgs e)
{
    try
    {
        List<string> Results = new List<string>();

        DatabaseDataContext dbc = new DatabaseDataContext();

        var data = dbc.SystemData
                      .Where(ac => ac.Account_id == tbAccount.Text)
                      .Where(ac => ac.TimeStamp == 0)
                      .Where(ac => ac.Category_id == tbCategory.Text)
                      .Where(ac => (int)ac.Category_seq_nbr == int.Parse(tbSequenceNumber.Text))
                      .Select(ac => ac.Unit_Code);

        Results.Add("Unit Code: " + data.First());

        e.Result = Results;
    }
    catch (Exception ex)
    {
        lbxData.Dispatcher.BeginInvoke( new Action(() => lbxData.Items.Add( "Exception Caught: " + ex.Message )));
    } 
}

No the problem was within the setup of the Lambdas for the Linq query. All the highlighted lines above is where the actual problem originates and not on the final highlighted line.

The problem was that I was accessing Gui controls data, and not changing; that was the nuance. For in my mind that was ok, it was a passive read action and not a direct writing one. Obviously not.

Note: If you have come to this blog experiencing this problem but for the writing of items to a control, one method to solve it is to use the Dispatcher off the control on any thread not just BackgroundWorker. That code is shown in my exception catch blog above. That line is perfectly fine to do and is not another issue. The lbxData is a Listbox on the main Xaml and because of the immediacy of the exception, I write

Resolution

Since I was already using the plumbing of the DoWorkEventArgs, it seemed a natural choice to pass in the data using that object. I changed the call to pass in a Dictionary of values to extract the data as such:

bcLoad.RunWorkerAsync(new Dictionary<string, string>() 
                        { 
                            { "AccountID",      tbAccount.Text }, 
                            { "CategoryID",     tbCategory.Text },
                            { "SequenceNumber", tbSequenceNumber.Text }
                        });

Then to consume the Dictionary as such:

void bcLoad_DoWork(object sender, DoWorkEventArgs e)
{
    try
    {
        List<string> Results = new List<string>();

        Dictionary<string, string> UserInputs = e.Argument as Dictionary<string, string>;

        if (UserInputs != null)
        {

        DatabaseContext dbc = new DatabaseContext();

        var data = dbc.SystemData
                      .Where(ac => ac.Account_ID == UserInputs["AccountID"])
                      .Where(ac => ac.TimeStamp == 0)
                      .Where(ac => ac.Category_id == UserInputs["CategoryID"])
                      .Where(ac => (int)ac.Category_seq_nbr == int.Parse(UserInputs["SequenceNumber"]))
                      .Select(ac => acc.UnitCode);

        Results.Add("Unit Code: " + data.First());

        e.Result = Results; // Pass the results to the completed events to process them accordingly.
        }
    }
    catch (Exception ex)
    {
        lbxData.Dispatcher.BeginInvoke( new Action(() => lbxData.Items.Add( "Exception Caught: " + ex.Message )));
    }

}

I simply convert the object property of Argument to a Dictionary, as highlighted, and go do the work. One doesn’t have to use a Dictionary. One can pass in any object off of the Argument property. Hope This Helps

Share

Tags: , , , ,

VS2010: Not Seeing the Obvious – Named Threads in Profile Reports

iStock_000002461629XSmallCall me crazy but I named my kids, I named my pets and heck, yes I even name my threads. Things which are important to me in life are worth naming; right? Thread names for me can be important in debug situations. When one uses the Performance Wizard and chooses to have a Concurrency Visualization profile report, specifically the Threads section the name of a thread is not used.

Historically and in the latest version of Visual Studio 2010 the profile reports ThreadMedo not show the thread names. Why?

Don’t get me wrong on this, Visual Studio Twenty Ten is a great product and light years ahead of all other versions! I look forward to having it share my cube and work computer for eight plus hours a day when it is finally released. But heck a man can dream can he?

Let us take a look at what inspires me to write this diminutive dissertation on a distilled user suggestion…

Premise

One can name threads, simply by, well naming it. Here is a code snippet below:

Thread T1 = new Thread(ThreadOne);

T1.Name = "Jabberwocky";

T1.Start();

Viola our thread is named. I cannot think of another reason for naming a thread except for debug purposes. Hey did someone mention debug?

Jabberwocky

Yep while debugging the nice little Threads window as shown above displays our named thread. But yet the Profile Performance reports do not show it. Are the two groups at Microsoft not talking to each other and sharing technology. 😉

Heck I even tried a trick to Trojan Horse a name into the profiler (Reference the Microsoft.VisualStudio.Profiler dll located in the install directory at  \Team Tools \Performance Tools\)

Thread t = new Thread(new ParameterizedThreadStart(
threadIndex =>
{
Microsoft.VisualStudio.Profiler.DataCollection.NameProfile(
"Jabberwocky",
Microsoft.VisualStudio.Profiler.ProfileLevel.Thread,
Microsoft.VisualStudio.Profiler.DataCollection.CurrentId
);

Console.WriteLine("Hello from thread " + (int)threadIndex);
}));

alas to no avail. The report still only shows the type of thread and its generic ID.

Why?

I feel that named threads might give one an edge in debugging race or deadlock conditions in code. This is a great tool which frankly could be made even better by including the actual thread names, if found in the report.

Connect Suggestion

If you find this little diatribe interesting go and put your two cents into the Microsoft Connect issue which I created:

Named Threads: Missing the Obvious on Profile Reports

Thanks for your time and well; taking a second look.

Share

Tags: , ,

Smart Resource Locking in C# .Net for Thread Safe Code

Updated 1/8/2012: Removed code formatting to use SyntaxHighlighter and fixed off colors on titles.

So you are into thread safe code and you have begun to lock resources. But the trap that all new programmers sometimes do is to lock the whole class as shown below:

public void DeadlockWaitingToHappen1(string change) 
{     
   lock (this)     
   {         
      _Resource1 = change;     
   } 
} 

public void DeadlockWaitingToHappen2(string change2) 
{     
   lock (this)     
   {         
      _Resource2 = change2;     
   } 
}

The problem with the above code, albeit trite due to the example, is that when a thread 1 calls the first method to change resource1, it will effectively block any other thread calling the opposite method to change _resource2.

Because we know that these resources are independent, such locking in the above case is a nuance, in a more advanced state, causes undo wait times for resources, but in a worse case scenario could cause deadlocks in code!

Solution

To get around that what we will do is to lock separate objects. The below code will create mirror object locks and use those to properly lock our different distinct resources.

// This class simulates the use of two different 
// thread safe resources and how to lock them 
// for thread safety but not block other 
// threads getting different resources. 
public class SmartLocking
{
    private string StrResource1 { get; set; }
    private string StrResource2 { get; set; }

    private object _Lock1 = new object();
    private object _Lock2 = new object();

    public void DoWorkOn1( string change )
    {
        lock (_Lock1)
        {
            _Resource1 = change;
        }
    }

    public void DoWorkOn2( string change2 )
    {
        lock (_Lock2)
        {
            _Resource2 = change2;
        }
    }
}

Summary

As you can see we have separate locks, so now thread 1 accessing resource 1 won’t block thread 2 accessing resource 2.  Note if the object you are working contains the interface to allow locking and it makes sense to use that resource, then lock it instead of a separate object.

Share

Tags: ,

Safely Update .Net Winform from Threads or Timer Ticks

Update The following article is one way to to achieve threading…But an easier way to try first is the BackGround Worker component (How to: Run an Operation in the Background). The below article shows how to invoke back to the form which is a step one does not have to do directly with the background worker due to its design.
Whenever one has threads or timers doing work on a winform application there is a need to update the screen from those operations. Most first time winform programmers fall into the trap where they try to update a screen control from those background processes and discover that their app locks up. The reason is that any data screen updating needs to be done by the GUI thread solely and not from any background task.
What the code should do is invoke a delegate back to the GUI thread to do the screen updating. This article shows one such way.
Step 1 define a delegate on the winform form class, and have an event derived from it which can be subscribed to such as:
// This is the format the delegate method
// will use when invoking back to the main gui
// thread.
public delegate void DataAcquired( object sender );
// The main thread will check for events
// invoked by subscribed threads here.
// This is the subscription point for the 
// threads.
public event DataAcquired OnDataAcquiredEvent;

In the above example we are just using an object to pass between the threads, but you can specify anything you want which is dictated by your circumstances.

Step 2 then have the form subscribe to the event (as in the constructor) which will be eventually be consumed by the worker threads or timers.

OnDataAcquiredEvent +=
    new DataAcquired(ThreadReportsDataAquiredEvent);

Note intellisense will do the above steps for you after the +=, accept them and it will do the next step

Step 3 Create the method that will handle the GUI update event

private void ThreadReportsDataAquiredEvent( object sender )
{
   tsslStatus.Text = sender.ToString();
}
  • Line 01: The thread/timer passes in an object which we will use to update the screen.
  • Line 03: We will take the object’s information from its ToString() and place it on a label on the form for the end user to see.

Step 4: In the timer tic method or the worker thread method we will call this method which will invoke back to the main thread:

private void PushStatus(string status)
{
    this.Invoke(this.OnDataAcquiredEvent,
                new object[] { status });
}

Note: One doesn’t have to create a separate method; the invoke line is all one has to do. We create the event and fire it to the GUI thread.

That is a safe way to update the screen for worker threads or timer tick events.

Share

Tags: , , , , ,