Ammar Khan
Ammar Khan

Reputation: 356

How to make async call using async and await keyword

I am using Linq To Twitter which support async and await feature.

I have win form app which call method inside dll to get Followers..(Currently, I am just returning back an integer but I want to return followers, don't know how to do this part)

 private void SubmitButton_Click(object sender, EventArgs e)
        {
            try
            {

                MessageBox.Show("Please wait for few mins");

                var maxFollowers = (MaxFollowers.Text == "") ? (int?)null : int.Parse(MaxFollowers.Text);

                var followers = TwitterHelper.GetFollowersTweets
                   (Convert.ToUInt64(TwitterUserID.Text), ConsumerKey.Text, ConsumerSecretKey.Text,
                       AccessToken.Text, AccessTokenSecret.Text, maxFollowers);


                MessageBox.Show(string.Format("Total Followers Found: {0}", followers.ToString()));

            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("Something went wrong!"));
            }
        }

The method which is call from Form

  public static int GetFollowersTweets
         (ulong twitterUserId, string consumerKey, string consumerKeySecret,
           string accessToken, string accessTokenSecret, int? maxFollowers)
        {


            var auth = GetUserAuthorizationToken
               (consumerKey, consumerKeySecret,
                   accessToken, accessTokenSecret);

            var followers = GetTwitterFollowers
              (twitterUserId, auth, maxFollowers);

            var followersTweets = new List<TwitterData>();

            followers.ContinueWith((taskWithMsg) =>
                                   {
                                       followersTweets = GetFollowersTweetsList(taskWithMsg.Result, auth);
                                   });



            return 2;


            // return followersTweets;

        }

The main method which fetch followers from Twitter API "GetTwitterFollowers"

 private static async Task<List<TwitterData>> GetTwitterFollowers(
         ulong twitterUserId, SingleUserAuthorizer auth, int? maxFollowers)
        {

            var followerss = maxFollowers ?? 15000;

            try
            {
                var twitterCtx = new TwitterContext(auth);
                var followers = await twitterCtx.Friendship
                                          .Where(f => f.Type == FriendshipType.FollowersList
                                              && f.UserID == twitterUserId.ToString())
                                          .Select(f => new TwitterData()
                                          {

                                              Followers = f.Users.Where(t => !t.Protected).Take(followerss).Select(s => s).ToList()
                                          }).SingleOrDefaultAsync();


                return GetFollowersList(followers.Followers);


            }
            catch (Exception ex)
            {
                return null;
            }

        }

Currently, the flow of my app is like this

1) When submit button click from MY Form, It call public method "GetFollowersTweets" which then call internal method "GetTwitterFollowers".. And this internal method is async, so when it start fetching the followers, the control return back to the public method again and it simply return an integer to the caller on the form...And after sometime, when twitter fetches the followers, it resume the rest of the task from the below line

 followers.ContinueWith((taskWithMsg) =>
                                       {
                                           followersTweets = GetFollowersTweetsList(taskWithMsg.Result, auth);
                                       });

As you can see, I simply returning an int, instead I want to return "followersTweets", how can I do that?? What changes are required? Please help

Upvotes: 0

Views: 180

Answers (2)

Stephen Cleary
Stephen Cleary

Reputation: 456537

As a general rule, do not use ContinueWith in asynchronous code; use await instead:

var followers = await GetTwitterFollowersAsync(twitterUserId, auth, maxFollowers);
var followersTweets = await GetFollowersTweetsListAsync(followers, auth);
return followersTweets;

I also changed your asynchronous methods to end in "Async", by convention.

This requires the signature of your method to change:

public static async Task<List<TwitterData>> GetFollowersTweetsAsync(...)

As well as the signature of your event handler:

private async void SubmitButton_Click(object sender, EventArgs e)
{
    ...
    var followers = await TwitterHelper.GetFollowersTweetsAsync
        (Convert.ToUInt64(TwitterUserID.Text), ConsumerKey.Text, ConsumerSecretKey.Text,
        AccessToken.Text, AccessTokenSecret.Text, maxFollowers);
    ...
}

Upvotes: 1

ntr
ntr

Reputation: 544

Instead of

        var followers = GetTwitterFollowers(twitterUserId, auth, maxFollowers);

        var followersTweets = new List<TwitterData>();

        followers.ContinueWith((taskWithMsg) =>
                               {
                                   followersTweets = GetFollowersTweetsList(taskWithMsg.Result, auth);
                               });



        return 2;

use

var followers = await GetTwitterFollowers(twitterUserId, auth, maxFollowers);
var followersList = await GetFollowersTweetsList(followers, auth);
return followersList.Count;

Also, you should change signature of GetFollowersTweets() to

public static async Task<int> GetFollowersTweets

Upvotes: 0

Related Questions