2

I have this code:

public class SalesforceAccess
{
    private static Salesforce.Force.ForceClient _sfclient;
    public static Salesforce.Force.ForceClient SFClient
    {
        get
        {
            if (_sfclient != null)
                return _sfclient;//-------------------------------------------------------------

            SetSFClient().Wait();
            return _sfclient;
        }
    }

    private static async Task SetSFClient()
    {
        //create auth client to retrieve token
        var auth = new AuthenticationClient();

        //get back URL and token
        //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        await auth.UsernamePasswordAsync(ConsumerKey, ConsumerSecret, Username, Password);
        //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

        var instanceUrl = auth.InstanceUrl;
        var accessToken = auth.AccessToken;
        var apiVersion = auth.ApiVersion;

        _sfclient = new ForceClient(instanceUrl, accessToken, apiVersion);
    }


    public static MyUser GetMyUser(string ID)
    {
        string query = "SELECT  Name, 
                ",City__c " +
                ",State__c " +
                "From SF_Table where " +
                "Name='+ID.ToString()+"'";

        //async call - create task and wait for completion          vvvvvvvvvvvvvvvv
        Task<Salesforce.Common.Models.QueryResult<object>> task = SFClient.QueryAsync<dynamic>(query);
        task.Wait();
        Salesforce.Common.Models.QueryResult<object> sfData = task.Result;

        <<Parse sfData>>
    }
}

If I use SalesforseAccess class from console application it works fine. However when I use it from the web MVC app on IIS it hangs at the following line:

await auth.UsernamePasswordAsync(ConsumerKey, ConsumerSecret, Username, Password);

Does anyone have an idea what may be happening here? Why does it behave differently? And how can this be avoided?

  • Can you show the code that is calling SetSFClient()? I suspect the deadlock is occurring there. Very generally speaking, you will need to propagate the usage of async/await further up your code. See Why does this async action hang? – Daniel Ballinger Jan 12 '17 at 21:09
  • @Daniel Ballinger (Sorry if you've got more than one notification) I have added a function that uses SF. My biggest confusion is why is it behaves differently. Is it because console app exits after the call and web app is running forever? Should I dispose AuthenticationClient? – shlasasha Jan 12 '17 at 22:16
0

There is a deadlock occurring on the UI thread. It is both stuck waiting for the result to come back AND waiting for the UI thread to become free so it can return the result on the captured context thread.

This is explained well in Why does this async action hang?.

You will need to follow one of the three suggested solutions:

  1. The preferred approach - make your GetMyUser method async. Continue propagating async/await as far back as you need to.
  2. Rewrite the Force.com .NET Toolkit so it doesn't use async/await or switch to another library that doesn't use it.
  3. Use .ConfigureAwait(continueOnCapturedContext: false) to override the default behavior of resuming on the captured context.
  • Rewrite the Force.com .NET Toolkit so it doesn't use async/await or switch to another library that doesn't use it auth.UsernamePasswordAsync(ConsumerKey, ConsumerSecret, Username, Password).**Wait()**; would do exactly that right? – shlasasha Jan 12 '17 at 23:07
  • @shlasasha No, it would still be using async/await. By rewrite I meant pull all the source code down from GitHub and remove any reference to the async/await keywords. I was being facetious. That's not really a practical solution as 1) it would be a lot of work. 2) you would then have to maintain your own library to work with the REST API. – Daniel Ballinger Jan 12 '17 at 23:12
  • 1
    You are right. But it did resolve my deadlock! – shlasasha Jan 17 '17 at 16:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.