示例#1
0
        public System.Threading.Tasks.Task <HttpWebHelperAsyncResult> ExecuteTaskAsync(IHttpWebRequest httpWebRequest, Stream requestBody, object state)
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource <HttpWebHelperAsyncResult>(state);

            try
            {
                ExecuteAsync(httpWebRequest, requestBody,
                             ar =>
                {
                    var asyncResult = (HttpWebHelperAsyncResult)ar;
                    if (asyncResult.IsCancelled)
                    {
                        tcs.TrySetCanceled();
                    }
                    if (asyncResult.Exception != null)
                    {
                        tcs.TrySetException(asyncResult.Exception);
                    }
                    else
                    {
                        tcs.TrySetResult(asyncResult);
                    }
                }, state);
            }
            catch (Exception ex)
            {
                tcs.TrySetException(ex);
            }

            return(tcs.Task);
        }
示例#2
0
        public System.Threading.Tasks.Task <FluentHttpAsyncResult> ExecuteTaskAsync(object state)
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource <FluentHttpAsyncResult>(state);

            try
            {
                ExecuteAsync(ar =>
                {
                    if (ar.IsCancelled)
                    {
                        tcs.TrySetCanceled();
                    }
                    if (ar.Exception != null)
                    {
                        tcs.TrySetException(ar.Exception);
                    }
                    else
                    {
                        tcs.TrySetResult(ar);
                    }
                }, state);
            }
            catch (Exception ex)
            {
                tcs.TrySetException(ex);
            }

            return(tcs.Task);
        }
示例#3
0
        public static void TransferCompletionToTask <T>(System.Threading.Tasks.TaskCompletionSource <T> tcs, System.ComponentModel.AsyncCompletedEventArgs e, Func <T> getResult, Action unregisterHandler)
        {
            if (e.UserState != tcs)
            {
                return;
            }

            try
            {
                unregisterHandler();
            }
            finally
            {
                if (e.Cancelled)
                {
                    tcs.TrySetCanceled();
                }
                else if (e.Error != null)
                {
                    tcs.TrySetException(e.Error);
                }
                else
                {
                    tcs.TrySetResult(getResult());
                }
            }
        }
示例#4
0
        public static System.Threading.Tasks.Task <eina.Value> WrapAsync(eina.Future future, CancellationToken token)
        {
            // Creates a task that will wait for SetResult for completion.
            // TaskCompletionSource is used to create tasks for 'external' Task sources.
            var tcs = new System.Threading.Tasks.TaskCompletionSource <eina.Value>();

            // Flag to be passed to the cancell callback
            bool fulfilled = false;

            future.Then((eina.Value received) => {
                    lock (future)
                    {
                        // Convert an failed Future to a failed Task.
                        if (received.GetValueType() == eina.ValueType.Error)
                        {
                            eina.Error err;
                            received.Get(out err);
                            if (err == eina.Error.ECANCELED)
                            {
                                tcs.SetCanceled();
                            }
                            else
                            {
                                tcs.TrySetException(new efl.FutureException(received));
                            }
                        }
                        else
                        {
                            // Will mark the returned task below as completed.
                            tcs.SetResult(received);
                        }
                        fulfilled = true;
                        return(received);
                    }
                });
            // Callback to be called when the token is cancelled.
            token.Register(() => {
                    lock (future)
                    {
                        // Will trigger the Then callback above with an eina.Error
                        if (!fulfilled)
                        {
                            future.Cancel();
                        }
                    }
                });

            return(tcs.Task);
        }
示例#5
0
        /// <summary>
        /// Send toast message to a windows phone device. If the app is active the user will recieve this message in the toast message callback. Otherwise the message
        /// appears as a notification on top of the screen. Clicking it will launch the app.
        /// </summary>
        /// <param name="toastTitle">The title of the toast message/</param>
        /// <param name="toastSubtitle">The subtitle of the toast message.</param>
        /// <param name="toastParameter">An optional parameter for the toast message.</param>
        /// <param name="senderUserId">The ID of the user that sent the notification.</param>
        /// <param name="deliverAfter">Schedule the message to be delivered after a certain date.</param>
        /// <param name="groupName">Send messages to an entire group of users, not just a one.</param>
        /// <returns>A Task&lt;Boolean&gt;that can be used to monitor progress on this call.</returns>
        public System.Threading.Tasks.Task <Boolean> SendToastMessageAsync(string toastTitle, string toastSubtitle, int senderUserId, string toastParameter = "", System.DateTime deliverAfter = default(DateTime), string groupName = "")
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource <Boolean>();

            SendToastMessageInternal(toastTitle, toastSubtitle, senderUserId, toastParameter, deliverAfter, groupName, (bcr) =>
            {
                if (bcr.Error != BuddyServiceClient.BuddyError.None)
                {
                    tcs.TrySetException(new BuddyServiceException(bcr.Error));
                }
                else
                {
                    tcs.TrySetResult(bcr.Result);
                }
            });
            return(tcs.Task);
        }
示例#6
0
        /// <summary>
        /// Send a image tile to a windows phone device. The tile is represented by a image URL, you can take a look at the Windows phone docs for image dimensions and formats.
        /// </summary>
        /// <param name="imageUri">The URL of the tile image.</param>
        /// <param name="senderUserId">The ID of the user that sent the notification.</param>
        /// <param name="messageCount">The message count for this tile.</param>
        /// <param name="messageTitle">The message title for the tile.</param>
        /// <param name="deliverAfter">Schedule the message to be delivered after a certain date.</param>
        /// <param name="groupName">Send messages to an entire group of users, not just a one.</param>
        /// <returns>A Task&lt;Boolean&gt;that can be used to monitor progress on this call.</returns>
        public System.Threading.Tasks.Task <Boolean> SendTileAsync(string imageUri, int senderUserId, int messageCount = -1, string messageTitle = "", System.DateTime deliverAfter = default(DateTime), string groupName = "")
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource <Boolean>();

            SendTileInternal(imageUri, senderUserId, messageCount, messageTitle, deliverAfter, groupName, (bcr) =>
            {
                if (bcr.Error != BuddyServiceClient.BuddyError.None)
                {
                    tcs.TrySetException(new BuddyServiceException(bcr.Error));
                }
                else
                {
                    tcs.TrySetResult(bcr.Result);
                }
            });
            return(tcs.Task);
        }
示例#7
0
        /// <summary>
        /// Get a paged list of registered devices for this Application. This list can then be used to iterate over the devices and send each user a push notification.
        /// </summary>
        /// <param name="forGroup">Optionally filter only devices in a certain group.</param>
        /// <param name="pageSize">Set the number of devices that will be returned for each call of this method.</param>
        /// <param name="currentPage">Set the current page.</param>
        /// <returns>A Task&lt;IEnumerable&lt;RegisteredDevice&gt; &gt;that can be used to monitor progress on this call.</returns>
        public System.Threading.Tasks.Task <IEnumerable <RegisteredDevice> > GetRegisteredDevicesAsync(string forGroup = "", int pageSize = 10, int currentPage = 1)
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource <IEnumerable <RegisteredDevice> >();

            GetRegisteredDevicesInternal(forGroup, pageSize, currentPage, (bcr) =>
            {
                if (bcr.Error != BuddyServiceClient.BuddyError.None)
                {
                    tcs.TrySetException(new BuddyServiceException(bcr.Error));
                }
                else
                {
                    tcs.TrySetResult(bcr.Result);
                }
            });
            return(tcs.Task);
        }
示例#8
0
        /// <summary>
        /// Register a Windows device for notificatons with Buddy. The URL is the notifications channel link that provided by the platform. Most of the time
        /// you don't need to call this API directly, you can use ConfigurePushAsync instead which will configure everyting for you. Note that if you call this method,
        /// you are responsible to configure the device for push notifications.
        /// </summary>
        /// <param name="deviceUri">The device notification channel URI.</param>
        /// <param name="enableTile">Optionally enable tile notifications</param>
        /// <param name="enableRaw">Optionally enable raw notifications.</param>
        /// <param name="enableToast">Optionally enable toast notifications.</param>
        /// <param name="groupName">Register this device as part of a group, so that you can send the whole group messages.</param>
        /// <returns>A Task&lt;Boolean&gt;that can be used to monitor progress on this call.</returns>
        public System.Threading.Tasks.Task <Boolean> RegisterDeviceAsync(string deviceUri, bool enableTile = true, bool enableRaw = true, bool enableToast = true, string groupName = "")
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource <Boolean>();

            RegisterDeviceInternal(deviceUri, enableTile, enableRaw, enableToast, groupName, (bcr) =>
            {
                if (bcr.Error != BuddyServiceClient.BuddyError.None)
                {
                    tcs.TrySetException(new BuddyServiceException(bcr.Error));
                }
                else
                {
                    tcs.TrySetResult(bcr.Result);
                }
            });
            return(tcs.Task);
        }
示例#9
0
        /// <summary>
        /// Searches for Player objects stored in the Buddy system. Searches can optionally be performed based on location.
        /// </summary>
        /// <param name="searchDistanceInMeters">The radius (in meters) around the specified location in which to look for locations. Pass in -1 to ignore this field.  </param>
        /// <param name="latitude">The latitude of the location around which to search for locations within the specified SearchDistance.   </param>
        /// <param name="longitude">The longitude of the location around which to search for locations within the specified SearchDistance. </param>
        /// <param name="recordLimit">The maximum number of search results to return or -1 to return all search results.    </param>
        /// <param name="boardName">Searches for scores which contain the specified board. Leave empty or pass in null if no board filter is to be used.    </param>
        /// <param name="onlyForLastNumberOfDays">The number of days into the past for which to look for scores. ie: passing in 5 will filter scores to include those which were added/updated on or after 5 days ago. Pass in -1 to ignore this filter.    </param>
        /// <param name="minimumScore">The minimum score value to search for. Pass in -1 to ignore this filter. </param>
        /// <param name="appTag">Searches for scores with the specified ApplicationTag stored with them. Leave empty or pass in null to ignore this filter. </param>
        /// <param name="rank">Optionally search for a player rank.</param>
        /// <returns>A Task&lt;IEnumerable&lt;GamePlayer&gt; &gt;that can be used to monitor progress on this call.</returns>
        public System.Threading.Tasks.Task <IEnumerable <GamePlayer> > FindAsync(int searchDistanceInMeters = -1, double latitude = 0, double longitude = 0, int recordLimit = 100, string boardName = "", int onlyForLastNumberOfDays = -1, int minimumScore = -1, string appTag = "", string rank = "")
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource <IEnumerable <GamePlayer> >();

            this.FindInternal(searchDistanceInMeters, latitude, longitude, recordLimit, boardName, onlyForLastNumberOfDays, minimumScore, appTag, rank, (bcr) =>
            {
                if (bcr.Error != BuddyServiceClient.BuddyError.None)
                {
                    tcs.TrySetException(new BuddyServiceException(bcr.Error));
                }
                else
                {
                    tcs.TrySetResult(bcr.Result);
                }
            });
            return(tcs.Task);
        }
示例#10
0
        /// <summary>
        /// Get all the player info for this user.
        /// </summary>
        /// <returns>A Task&lt;GamePlayer&gt;that can be used to monitor progress on this call.</returns>
        public System.Threading.Tasks.Task <GamePlayer> GetInfoAsync()
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource <GamePlayer>();

            this.GetInfoInternal((bcr) =>
            {
                if (bcr.Error != BuddyServiceClient.BuddyError.None)
                {
                    tcs.TrySetException(new BuddyServiceException(bcr.Error));
                }
                else
                {
                    tcs.TrySetResult(bcr.Result);
                }
            });
            return(tcs.Task);
        }
示例#11
0
        /// <summary>
        /// Updates one or more fields of an existing Player object which was previously created.
        /// </summary>
        /// <param name="name">The name of the new player.</param>
        /// <param name="board">An optional name of a "Board" for the game. Used for grouping scores together either by user group, levels, or some other method relevant to the game. Although optional, a value is recommended such as "Default" for use in later searches of scores. If no board is to be stored, then pass in null or leave empty.</param>
        /// <param name="rank">An optional ranking to associate with the score. Can be any string ie: descriptions of achievements, ranking strings like "excellent", etc. Pass in null or an empty string if you do not wish to store a rank</param>
        /// <param name="latitude">The latitude of the location where the Player object is being updated.</param>
        /// <param name="longitude">The longitude of the location where the Player object is being updated. </param>
        /// <param name="appTag">Optional metadata to store with the Player object. ie: a list of players, game state, etc. Leave empty or set to null if there is no data to store with the score.</param>
        /// <returns>A Task&lt;Boolean&gt;that can be used to monitor progress on this call.</returns>
        public System.Threading.Tasks.Task <Boolean> UpdateAsync(string name, string board = "", string rank = "", double latitude = 0, double longitude = 0, string appTag = "")
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource <Boolean>();

            this.UpdateInternal(name, board, rank, latitude, longitude, appTag, (bcr) =>
            {
                if (bcr.Error != BuddyServiceClient.BuddyError.None)
                {
                    tcs.TrySetException(new BuddyServiceException(bcr.Error));
                }
                else
                {
                    tcs.TrySetResult(bcr.Result);
                }
            });
            return(tcs.Task);
        }
示例#12
0
        /// <summary>
        /// Get a photo album by its name. Note that there can be more than one album with the same name. This method will only return the first one.
        /// Call PhotoAlbums.All to get all the albums.
        /// </summary>
        /// <param name="albumName">The name of the albul to retrieve. Can't be null or empty.</param>
        /// <returns>A Task&lt;PhotoAlbum&gt;that can be used to monitor progress on this call.</returns>
        public System.Threading.Tasks.Task <PhotoAlbum> GetAsync(string albumName)
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource <PhotoAlbum>();

            GetInternal(albumName, (bcr) =>
            {
                if (bcr.Error != BuddyServiceClient.BuddyError.None)
                {
                    tcs.TrySetException(new BuddyServiceException(bcr.Error));
                }
                else
                {
                    tcs.TrySetResult(bcr.Result);
                }
            });
            return(tcs.Task);
        }
示例#13
0
        /// <summary>
        /// Record runtime crash information for this app. This could be exceptions, errors or your own custom crash information.
        /// </summary>
        /// <param name="methodName">The method name or location where the error happend. This could also be a descriptive string of the error.</param>
        /// <param name="osVersion">The OS version of the device runnign this code. On some .NET platforms you can use System.Environment.OSVersion to get this information.</param>
        /// <param name="deviceType">The type of device running this app. On Windows Phone 7 for example you can use DeviceExtendedProperties to retrieve this information.</param>
        /// <param name="user">The user that's registering this device information.</param>
        /// <param name="stackTrace">The optional stack trace of where the error happened.</param>
        /// <param name="appVersion">The optional version of this application.</param>
        /// <param name="latitude">The optional latitude where this report was submitted.</param>
        /// <param name="longitude">The optional longiture where this report was submitted.</param>
        /// <param name="metadata">An optional application specific metadata string to include with the report.</param>
        /// <returns>A Task&lt;Boolean&gt;that can be used to monitor progress on this call.</returns>
        public System.Threading.Tasks.Task <Boolean> RecordCrashAsync(string methodName, string osVersion, string deviceType, Buddy.AuthenticatedUser user, string stackTrace = "", string appVersion = "1.0", double latitude = 0, double longitude = 0, string metadata = "")
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource <Boolean>();

            RecordCrashInternal(methodName, osVersion, deviceType, user, stackTrace, appVersion, latitude, longitude, metadata, (bcr) =>
            {
                if (bcr.Error != BuddyServiceClient.BuddyError.None)
                {
                    tcs.TrySetException(new BuddyServiceException(bcr.Error));
                }
                else
                {
                    tcs.TrySetResult(bcr.Result);
                }
            });
            return(tcs.Task);
        }
示例#14
0
        /// <summary>
        /// Add a new picture to this album. Note that this method internally does two web-service calls, and the IAsyncResult object
        /// returned is only valid for the first one.
        /// </summary>
        /// <param name="photoStream">A stream containing the photo's contents..</param>
        /// <param name="comment">An optional comment for this picture.</param>
        /// <param name="latitude">An optional latitude for the picture.</param>
        /// <param name="longitude">An optional longitude for the picture.</param>
        /// <param name="appTag">An optional application tag.</param>
        /// <param name="watermarkmessage">An optional message to watermark the image with.</param>
        /// <returns>A Task&lt;Picture&gt;that can be used to monitor progress on this call.</returns>
        public System.Threading.Tasks.Task <Picture> AddPictureWithWatermarkAsync(Stream photoStream, string comment = "", double latitude = 0, double longitude = 0, string appTag = "", string watermarkmessage = "")
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource <Picture>();

            AddPictureWithWatermarkInternal(photoStream, comment, latitude, longitude, appTag, watermarkmessage, (bcr) =>
            {
                if (bcr.Error != BuddyServiceClient.BuddyError.None)
                {
                    tcs.TrySetException(new BuddyServiceException(bcr.Error));
                }
                else
                {
                    tcs.TrySetResult(bcr.Result);
                }
            });
            return(tcs.Task);
        }
示例#15
0
        /// <summary>
        /// Search for game scores based on a number of different parameters.
        /// </summary>
        /// <param name="user">Optionally limit the search to a spcific user.</param>
        /// <param name="distanceInMeters">Optionally specify a distance from a lat/long to search on. By default this is ignored.</param>
        /// <param name="latitude">Optional latitude where we can start the search.</param>
        /// <param name="longitude">Optional longitude where we can start the search.</param>
        /// <param name="recordLimit">Optionally limit the number of records returned by this search.</param>
        /// <param name="boardName">Optionally filter on a specific board name.</param>
        /// <param name="daysOld">Optionally only return scores that are X number of days old.</param>
        /// <param name="minimumScore">Optionally only return scores that are above a certain minimum score.</param>
        /// <param name="appTag">Optionally return only scores that have a certain app tag.</param>
        /// <returns>A Task&lt;IEnumerable&lt;GameScore&gt; &gt;that can be used to monitor progress on this call.</returns>
        public System.Threading.Tasks.Task <IEnumerable <GameScore> > FindScoresAsync(Buddy.User user = null, int distanceInMeters = -1, double latitude = 0, double longitude = 0, int recordLimit = 100, string boardName = "", int daysOld = 999999, double minimumScore = -1, string appTag = "")
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource <IEnumerable <GameScore> >();

            this.FindScoresInternal(user, distanceInMeters, latitude, longitude, recordLimit, boardName, daysOld, minimumScore, appTag, (bcr) =>
            {
                if (bcr.Error != BuddyServiceClient.BuddyError.None)
                {
                    tcs.TrySetException(new BuddyServiceException(bcr.Error));
                }
                else
                {
                    tcs.TrySetResult(bcr.Result);
                }
            });
            return(tcs.Task);
        }
示例#16
0
        /// <summary>
        /// Return all photo albums for this user. Note that this can be an expensive operation since all the Picture data is retrieved as well.
        /// </summary>
        /// <param name="afterDate">Optionally return all albums created after a date.</param>
        /// <returns>A Task&lt;IEnumerable&lt;PhotoAlbum&gt; &gt;that can be used to monitor progress on this call.</returns>
        public System.Threading.Tasks.Task <IEnumerable <PhotoAlbum> > GetAllAsync(System.DateTime afterDate = default(DateTime))
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource <IEnumerable <PhotoAlbum> >();

            GetAllInternal(afterDate, (bcr) =>
            {
                if (bcr.Error != BuddyServiceClient.BuddyError.None)
                {
                    tcs.TrySetException(new BuddyServiceException(bcr.Error));
                }
                else
                {
                    tcs.TrySetResult(bcr.Result);
                }
            });
            return(tcs.Task);
        }
示例#17
0
        /// <summary>
        /// This method returns the sum of a set of metadata items that correspond to a certain key wildcard. Note that the values of these items
        /// need to be numbers or floats, otherwise this method will fail.
        /// Unlike the 'Sum' method this method can take a list of keys separated by semicolons and will return a list of sums for all of those keys.
        /// </summary>
        /// <param name="forKeys">The key to use to filter the items that need to be summed. Is always treated as a wildcard.</param>
        /// <param name="withinDistance">Optionally sum only items within a certain number of meters from lat/long.</param>
        /// <param name="latitude">Optionally provide a latitude where the search can be started from.</param>
        /// <param name="longitude">Optionally provide a longitude where the search can be started from.</param>
        /// <param name="updatedMinutesAgo">Optionally sum only on items that have been update a number of minutes ago.</param>
        /// <param name="withAppTag">Optionally sum only items that have a certain application tag.</param>
        /// <returns>A Task&lt;IEnumerable&lt;MetadataSum&gt; &gt;that can be used to monitor progress on this call.</returns>
        public System.Threading.Tasks.Task <IEnumerable <MetadataSum> > BatchSumAsync(string forKeys, string withinDistance = "-1", double latitude = -1, double longitude = -1, int updatedMinutesAgo = -1, string withAppTag = "")
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource <IEnumerable <MetadataSum> >();

            this.BatchSumInternal(forKeys, withinDistance, latitude, longitude, updatedMinutesAgo, withAppTag, (bcr) =>
            {
                if (bcr.Error != BuddyServiceClient.BuddyError.None)
                {
                    tcs.TrySetException(new BuddyServiceException(bcr.Error));
                }
                else
                {
                    tcs.TrySetResult(bcr.Result);
                }
            });
            return(tcs.Task);
        }
示例#18
0
        /// <summary>
        /// Delete this photo album.
        /// </summary>
        /// <returns>A Task&lt;Boolean&gt;that can be used to monitor progress on this call.</returns>
        public System.Threading.Tasks.Task <Boolean> DeleteAsync()
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource <Boolean>();

            DeleteInternal((bcr) =>
            {
                if (bcr.Error != BuddyServiceClient.BuddyError.None)
                {
                    tcs.TrySetException(new BuddyServiceException(bcr.Error));
                }
                else
                {
                    tcs.TrySetResult(bcr.Result);
                }
            });
            return(tcs.Task);
        }
示例#19
0
        /// <summary>
        /// Get all the metadata items for this application. Note that this can be a very expensive method, try to retrieve specific items if possible
        /// or do a search.
        /// </summary>
        /// <returns>A Task&lt;IDictionary&lt;String,MetadataItem&gt; &gt;that can be used to monitor progress on this call.</returns>
        public System.Threading.Tasks.Task <IDictionary <String, MetadataItem> > GetAllAsync()
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource <IDictionary <String, MetadataItem> >();

            this.GetAllInternal((bcr) =>
            {
                if (bcr.Error != BuddyServiceClient.BuddyError.None)
                {
                    tcs.TrySetException(new BuddyServiceException(bcr.Error));
                }
                else
                {
                    tcs.TrySetResult(bcr.Result);
                }
            });
            return(tcs.Task);
        }
示例#20
0
        /// <summary>
        /// This method is used create a new album. The album will be owned by this user. Multiple albums can be created with the same name. Note that this method internally does two web-service calls, and the IAsyncResult object
        /// returned is only valid for the first one.
        /// </summary>
        /// <param name="name">The name of the new album.</param>
        /// <param name="isPublic">Make the album publicly visible to other users.</param>
        /// <param name="appTag">Optionally add a custom application tag for this user.</param>
        /// <returns>A Task&lt;PhotoAlbum&gt;that can be used to monitor progress on this call.</returns>
        public System.Threading.Tasks.Task <PhotoAlbum> CreateAsync(string name, bool isPublic = false, string appTag = "")
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource <PhotoAlbum>();

            CreateInternal(name, isPublic, appTag, (bcr) =>
            {
                if (bcr.Error != BuddyServiceClient.BuddyError.None)
                {
                    tcs.TrySetException(new BuddyServiceException(bcr.Error));
                }
                else
                {
                    tcs.TrySetResult(bcr.Result);
                }
            });
            return(tcs.Task);
        }
示例#21
0
        /// <summary>
        /// Get a metadata item with a key. The key can't be null or an empty string.
        /// </summary>
        /// <param name="key">The key to use to reference the metadata item.</param>
        /// <returns>A Task&lt;MetadataItem&gt;that can be used to monitor progress on this call.</returns>
        public System.Threading.Tasks.Task <MetadataItem> GetAsync(string key)
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource <MetadataItem>();

            this.GetInternal(key, (bcr) =>
            {
                if (bcr.Error != BuddyServiceClient.BuddyError.None)
                {
                    tcs.TrySetException(new BuddyServiceException(bcr.Error));
                }
                else
                {
                    tcs.TrySetResult(bcr.Result);
                }
            });
            return(tcs.Task);
        }
示例#22
0
        /// <summary>
        /// Set a metadata item value for a key. You can additional add latitude and longitude coordinate to record the location
        /// from where this item was set, or tag the item with a custom tag.
        /// The item doesn't have to exist to be set, this method acts as an Add method in cases where the item doesn't exist.
        /// </summary>
        /// <param name="key">The key of the metadata item, can't be null or empty.</param>
        /// <param name="value">The value of the metadata item, can't be null.</param>
        /// <param name="latitude">The optional latitude of the metadata item.</param>
        /// <param name="longitude">The optional longitude of the metadata item.</param>
        /// <param name="appTag">The optional application tag for this item.</param>
        /// <returns>A Task&lt;Boolean&gt;that can be used to monitor progress on this call.</returns>
        public System.Threading.Tasks.Task <Boolean> SetAsync(string key, string value, double latitude = 0, double longitude = 0, string appTag = "")
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource <Boolean>();

            this.SetInternal(key, value, latitude, longitude, appTag, (bcr) =>
            {
                if (bcr.Error != BuddyServiceClient.BuddyError.None)
                {
                    tcs.TrySetException(new BuddyServiceException(bcr.Error));
                }
                else
                {
                    tcs.TrySetResult(bcr.Result);
                }
            });
            return(tcs.Task);
        }
示例#23
0
        /// <summary>
        /// Search for metadata items in this application. Note that this method will only find app-level metadata items.
        /// </summary>
        /// <param name="searchDistanceMeters">The distance in meters from the latitude and longitude to search in. To ignore this distance pass in 40075000 (the circumferance of the earth).</param>
        /// <param name="latitude">The latitude from where the saerch will start.</param>
        /// <param name="longitude">The longitude from where the saerch will start.</param>
        /// <param name="numberOfResults">Optionally limit the number of returned metadata items.</param>
        /// <param name="withKey">Optionally search for items with a specific key. The value of this parameter is treated as a wildcard.</param>
        /// <param name="withValue">Optionally search for items with a specific value. The value of this parameter is treated as a wildcard.</param>
        /// <param name="updatedMinutesAgo">Optionally return only items that were updated some minutes ago.</param>
        /// <param name="valueMin">Optionally search for metadata item values that are bigger than this number.</param>
        /// <param name="valueMax">Optionally search for metadata item values that are smaller than this number.</param>
        /// <param name="searchAsFloat">Optionally treat all metadata values as floats. Useful for min/max searches.</param>
        /// <param name="sortAscending">Optionally sort the results ascending.</param>
        /// <param name="disableCache">Optionally disable cache searches.</param>
        /// <returns>A Task&lt;IDictionary&lt;String,MetadataItem&gt; &gt;that can be used to monitor progress on this call.</returns>
        public System.Threading.Tasks.Task <IDictionary <String, MetadataItem> > FindAsync(int searchDistanceMeters, double latitude, double longitude, int numberOfResults = 10, string withKey = "", string withValue = "", int updatedMinutesAgo = -1, double valueMin = 0, double valueMax = 100, bool searchAsFloat = false, bool sortAscending = false, bool disableCache = false)
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource <IDictionary <String, MetadataItem> >();

            this.FindInternal(searchDistanceMeters, latitude, longitude, numberOfResults, withKey, withValue, updatedMinutesAgo, valueMin, valueMax, searchAsFloat, sortAscending, disableCache, (bcr) =>
            {
                if (bcr.Error != BuddyServiceClient.BuddyError.None)
                {
                    tcs.TrySetException(new BuddyServiceException(bcr.Error));
                }
                else
                {
                    tcs.TrySetResult(bcr.Result);
                }
            });
            return(tcs.Task);
        }
示例#24
0
        /// <summary>
        /// Gets a list of lowest scores for a specific game board.
        /// </summary>
        /// <param name="boardName">The board name can be a specific string or a 'LIKE' pattern using %.</param>
        /// <param name="recordLimit">The maximum number of scores to return.</param>
        /// <returns>A Task&lt;IEnumerable&lt;GameScore&gt; &gt;that can be used to monitor progress on this call.</returns>
        public System.Threading.Tasks.Task <IEnumerable <GameScore> > GetLowScoresAsync(string boardName, int recordLimit = 100)
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource <IEnumerable <GameScore> >();

            GetLowScoresInternal(boardName, recordLimit, (bcr) =>
            {
                if (bcr.Error != BuddyServiceClient.BuddyError.None)
                {
                    tcs.TrySetException(new BuddyServiceException(bcr.Error));
                }
                else
                {
                    tcs.TrySetResult(bcr.Result);
                }
            });
            return(tcs.Task);
        }
示例#25
0
        /// <summary>
        /// Gets a list of profile photos for this user.
        /// </summary>
        /// <returns>A Task&lt;IEnumerable&lt;PicturePublic&gt; &gt;that can be used to monitor progress on this call.</returns>
        public System.Threading.Tasks.Task <IEnumerable <PicturePublic> > GetProfilePhotosAsync()
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource <IEnumerable <PicturePublic> >();

            GetProfilePhotosInternal((bcr) =>
            {
                if (bcr.Error != BuddyServiceClient.BuddyError.None)
                {
                    tcs.TrySetException(new BuddyServiceException(bcr.Error));
                }
                else
                {
                    tcs.TrySetResult(bcr.Result);
                }
            });
            return(tcs.Task);
        }
示例#26
0
        /// <summary>Asynchronously write a sequence of bytes from the USB pipe.</summary>
        /// <param name="buffer">Buffer that will receive the data read from the pipe.</param>
        /// <param name="offset">Byte offset within the buffer at which to begin writing the data received.</param>
        /// <param name="length">Length of the data to transfer.</param>
        /// <returns>
        ///     A task that represents the asynchronous read operation.
        ///     The value of the TResult parameter contains the total number of bytes that has been transferred.
        ///     The result value can be less than the number of bytes requested if the number of bytes currently available is less than the requested number,
        ///     or it can be 0 (zero) if the end of the stream has been reached.
        /// </returns>
        public System.Threading.Tasks.Task <int> WriteAsync(byte[] buffer, int offset, int length)
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource <int>();

            this.BeginWrite(buffer, offset, length, (iar) =>
            {
                try
                {
                    tcs.TrySetResult(this.EndWrite(iar));
                }
                catch (Exception ex)
                {
                    tcs.TrySetException(ex);
                }
            }, null);

            return(tcs.Task);
        }
 public System.Threading.Tasks.Task<IEnumerable<User>> FindUserAsync(double latitude = 0, double longitude = 0, uint searchDistance = 2147483647, uint recordLimit = 10, Buddy.UserGender gender = UserGender.Any, uint ageStart = 0, uint ageStop = 200, Buddy.UserStatus status = UserStatus.Any, uint checkinsWithinMinutes = 2147483647, string appTag = "")
 {
     var tcs = new System.Threading.Tasks.TaskCompletionSource<IEnumerable<User>>();
     FindUserInternal(latitude, longitude, searchDistance, recordLimit, gender, ageStart, ageStop, status, checkinsWithinMinutes, appTag, (bcr) =>
     {
         if (bcr.Error != BuddyServiceClient.BuddyError.None)
         {
             tcs.TrySetException(new BuddyServiceException(bcr.Error));
         }
         else
         {
             tcs.TrySetResult(bcr.Result);
         }
     });
     return tcs.Task;
 }
 /// <summary>
 /// Get a list of user check-in locations.
 /// </summary>
 /// <param name="afterDate">Filter the list to return only check-in after a date.</param>
 /// <returns>A Task&lt;IEnumerable&lt;CheckInLocation&gt; &gt;that can be used to monitor progress on this call.</returns>
 public System.Threading.Tasks.Task<IEnumerable<CheckInLocation>> GetCheckInsAsync(System.DateTime afterDate = default(DateTime))
 {
     var tcs = new System.Threading.Tasks.TaskCompletionSource<IEnumerable<CheckInLocation>>();
     GetCheckInsInternal(afterDate, (bcr) =>
     {
         if (bcr.Error != BuddyServiceClient.BuddyError.None)
         {
             tcs.TrySetException(new BuddyServiceException(bcr.Error));
         }
         else
         {
             tcs.TrySetResult(bcr.Result);
         }
     });
     return tcs.Task;
 }
 /// <summary>
 /// Check-in the user at a location.
 /// </summary>
 /// <param name="latitude">The latitude of the location.</param>
 /// <param name="longitude">The longitude of the location.</param>
 /// <param name="comment">An optional comment for the check-in.</param>
 /// <param name="appTag">An optional application specific tag for the location.</param>
 /// <returns>A Task&lt;Boolean&gt;that can be used to monitor progress on this call.</returns>
 public System.Threading.Tasks.Task<Boolean> CheckInAsync(double latitude, double longitude, string comment = "", string appTag = "")
 {
     var tcs = new System.Threading.Tasks.TaskCompletionSource<Boolean>();
     CheckInInternal(latitude, longitude, comment, appTag, (bcr) =>
     {
         if (bcr.Error != BuddyServiceClient.BuddyError.None)
         {
             tcs.TrySetException(new BuddyServiceException(bcr.Error));
         }
         else
         {
             tcs.TrySetResult(bcr.Result);
         }
     });
     return tcs.Task;
 }
 /// <summary>
 /// Update the profile of this user.
 /// </summary>
 /// <param name="name">Optional new name for the user, can't be null or empty.</param>
 /// <param name="password">Optional new password for the user, can't be null.</param>
 /// <param name="gender">Optional new gender for the user.</param>
 /// <param name="age">Optional new age for the user.</param>
 /// <param name="email">Optional new email for the user.</param>
 /// <param name="status">Optional new status for the user.</param>
 /// <param name="fuzzLocation">Optional change in location fuzzing for this user. If location fuzzing is enable, user location will be 
 /// randomized in all searches by other users.</param>
 /// <param name="celebrityMode">Optional change in celebrity mode for this user. If celebrity mode is enabled the user will be hidden from all searches in the system.</param>
 /// <param name="appTag">Optional update to the custom application tag for this user.</param>
 /// <returns>A Task&lt;Boolean&gt;that can be used to monitor progress on this call.</returns>
 public System.Threading.Tasks.Task<Boolean> UpdateAsync(string name = "", string password = "", Buddy.UserGender gender = UserGender.Any, int age = 0, string email = "", Buddy.UserStatus status = UserStatus.Any, bool fuzzLocation = false, bool celebrityMode = false, string appTag = "")
 {
     var tcs = new System.Threading.Tasks.TaskCompletionSource<Boolean>();
     UpdateInternal(name, password, gender, age, email, status, fuzzLocation, celebrityMode, appTag, (bcr) =>
     {
         if (bcr.Error != BuddyServiceClient.BuddyError.None)
         {
             tcs.TrySetException(new BuddyServiceException(bcr.Error));
         }
         else
         {
             tcs.TrySetResult(bcr.Result);
         }
     });
     return tcs.Task;
 }
 public  System.Threading.Tasks.Task<Buddy.User> FindUser(string userNameToFetch)
 {
           var tcs = new System.Threading.Tasks.TaskCompletionSource<User>();
           this.FindUserInternal(userNameToFetch,  (bcr) =>
           {
               if (bcr.Error != BuddyServiceClient.BuddyError.None)
               {
                   tcs.TrySetException(new BuddyServiceException(bcr.Error));
               }
               else
               {
                   tcs.TrySetResult(bcr.Result);
               }
           });
           return tcs.Task;
 }
示例#32
0
 /// <summary>
 /// Returns a list of supported filters that can be applied to this picture. Example filters are: Hue Shift, Crop, etc.
 /// </summary>
 /// <returns>A Task&lt;IDictionary&lt;String,String&gt; &gt;that can be used to monitor progress on this call.</returns>
 public System.Threading.Tasks.Task<IDictionary<String, String>> SupportedFiltersAsync()
 {
     var tcs = new System.Threading.Tasks.TaskCompletionSource<IDictionary<String, String>>();
     SupportedFiltersInternal((bcr) =>
     {
         if (bcr.Error != BuddyServiceClient.BuddyError.None)
         {
             tcs.TrySetException(new BuddyServiceException(bcr.Error));
         }
         else
         {
             tcs.TrySetResult(bcr.Result);
         }
     });
     return tcs.Task;
 }
        /// <summary>
        /// Configure this Windows Phone device for push notifications
        /// </summary>
        /// <param name="channelName"></param>
        /// <param name="enableTiles"></param>
        /// <param name="enableToastMessages"></param>
        /// <param name="groupName"></param>
        /// <param name="allowedDomains"></param>
        /// <param name="rawMessageCallback"></param>
        /// <param name="toastMessageCallback"></param>
        public System.Threading.Tasks.Task<Boolean> ConfigurePushAsync(bool enableTiles, bool enableToastMessages, string groupName = "",
            List<string> allowedDomains = null, Action<string> rawMessageCallback = null, Action<IDictionary<string, string>> toastMessageCallback = null, string channelName = null)
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource<Boolean>();

            Action<bool, Exception> finish = (result, ex) =>
            {
                if (ex != null)
                {
                    tcs.TrySetException(ex);
                }
                else
                {
                    tcs.TrySetResult(result);
                }
            };
           
            if (allowedDomains == null) allowedDomains = new List<string>();
            allowedDomains.Add("http://buddyplatform.s3.amazonaws.com/");
            
            channelName = this.GetChannelName(channelName);

            HttpNotificationChannel channel = null;
            bool done = false;
            if ((channel = HttpNotificationChannel.Find(channelName)) == null)
            {
                channel = new HttpNotificationChannel(channelName, "www.buddy.com");
                if (channel == null)
                {
                    Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        finish(false, new Exception("Couldn't create HttpNotificationChannel."));
                    });

                    done = true;
                }
                else
                {
                    channel.Open();
                }
            }

            if (!done && rawMessageCallback != null) channel.HttpNotificationReceived += (s, ev) =>
            {
                StreamReader reader = new StreamReader(ev.Notification.Body);

                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    rawMessageCallback(reader.ReadToEnd());
                });
            };


            if (!done && toastMessageCallback != null) channel.ShellToastNotificationReceived += (s, ev) =>
            {
                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    toastMessageCallback(ev.Collection);
                });
            };

            Action<HttpNotificationChannel> registerUri = (newChannel) =>
            {
                if (enableTiles)
                {
                    BindTile(newChannel, allowedDomains);
                }

                if (enableToastMessages)
                {
                    BindToast(newChannel);
                }

                this.RegisterDeviceInternal(newChannel.ChannelUri.ToString(), enableTiles, rawMessageCallback != null, enableToastMessages, groupName, (bcr) =>
                {
                   
                    finish(bcr.Result, bcr.Error == BuddyError.None ? null : new BuddyServiceException(bcr.Error.ToString()));
                   
                });

              
            };

            if (!done)
            {
                channel.ChannelUriUpdated += (s, ev) =>
                {
                    registerUri(channel);
                };

                if (channel.ChannelUri != null)
                {
                    registerUri(channel);
                }
            }
            return tcs.Task;
        }
 /// <summary>
 /// Search for public albums from other users.
 /// </summary>
 /// <param name="searchDistanceInMeters">Optionally search only within a certain distance from the supplied lat/long.</param>
 /// <param name="latitude">Optionally search for photos added near a latitude.</param>
 /// <param name="longitude">Optionally search for photos added near a longitude.</param>
 /// <param name="limitResults">Optionally limit the number of returned photos. Note that this parameter limits the photos returned, not albums. It's possible
 /// that a partial album is returned.</param>
 /// <returns>A Task&lt;IEnumerable&lt;PhotoAlbumPublic&gt; &gt;that can be used to monitor progress on this call.</returns>
 public System.Threading.Tasks.Task<IEnumerable<PhotoAlbumPublic>> SearchForAlbumsAsync(int searchDistanceInMeters = 99999999, double latitude = 0, double longitude = 0, int limitResults = 50)
 {
     var tcs = new System.Threading.Tasks.TaskCompletionSource<IEnumerable<PhotoAlbumPublic>>();
     SearchForAlbumsInternal(searchDistanceInMeters, latitude, longitude, limitResults, (bcr) =>
     {
         if (bcr.Error != BuddyServiceClient.BuddyError.None)
         {
             tcs.TrySetException(new BuddyServiceException(bcr.Error));
         }
         else
         {
             tcs.TrySetResult(bcr.Result);
         }
     });
     return tcs.Task;
 }
 /// <summary>
 /// Retrieve a picture by its unique ID. Any picture that the user owns or is publicly available can be retrieved.
 /// </summary>
 /// <param name="pictureId">The id of the picture to retrieve.</param>
 /// <returns>A Task&lt;Picture&gt;that can be used to monitor progress on this call.</returns>
 public System.Threading.Tasks.Task<Picture> GetPictureAsync(int pictureId)
 {
     var tcs = new System.Threading.Tasks.TaskCompletionSource<Picture>();
     GetPictureInternal(pictureId, (bcr) =>
     {
         if (bcr.Error != BuddyServiceClient.BuddyError.None)
         {
             tcs.TrySetException(new BuddyServiceException(bcr.Error));
         }
         else
         {
             tcs.TrySetResult(bcr.Result);
         }
     });
     return tcs.Task;
 }
示例#36
0
 /// <summary>
 /// Delete this photo album.
 /// </summary>
 /// <returns>A Task&lt;Boolean&gt;that can be used to monitor progress on this call.</returns>
 public System.Threading.Tasks.Task<Boolean> DeleteAsync()
 {
     var tcs = new System.Threading.Tasks.TaskCompletionSource<Boolean>();
     DeleteInternal((bcr) =>
     {
         if (bcr.Error != BuddyServiceClient.BuddyError.None)
         {
             tcs.TrySetException(new BuddyServiceException(bcr.Error));
         }
         else
         {
             tcs.TrySetResult(bcr.Result);
         }
     });
     return tcs.Task;
 }
 /// <summary>
 /// Set a new "active" profile photo from the list of profile photos that the user has uploaded. The photo needs to be already uploaded.
 /// </summary>
 /// <param name="picture">The photo to set as the "active" profile photo.</param>
 /// <returns>A Task&lt;Boolean&gt;that can be used to monitor progress on this call.</returns>
 public System.Threading.Tasks.Task<Boolean> SetProfilePhotoAsync(Buddy.PicturePublic picture)
 {
     var tcs = new System.Threading.Tasks.TaskCompletionSource<Boolean>();
     SetProfilePhotoInternal(picture, (bcr) =>
     {
         if (bcr.Error != BuddyServiceClient.BuddyError.None)
         {
             tcs.TrySetException(new BuddyServiceException(bcr.Error));
         }
         else
         {
             tcs.TrySetResult(bcr.Result);
         }
     });
     return tcs.Task;
 }
 /// <summary>
 /// Add a profile photo for this user.
 /// </summary>
 /// <param name="photoSteam">An array of bytes that represent the image you are adding.</param>
 /// <param name="appTag">An optional tag for the photo.</param>
 /// <returns>A Task&lt;Boolean&gt;that can be used to monitor progress on this call.</returns>
 public System.Threading.Tasks.Task<Boolean> AddProfilePhotoAsync(Stream photoSteam, string appTag = "")
 {
     var tcs = new System.Threading.Tasks.TaskCompletionSource<Boolean>();
     AddProfilePhotoInternal(photoSteam, appTag, (bcr) =>
     {
         if (bcr.Error != BuddyServiceClient.BuddyError.None)
         {
             tcs.TrySetException(new BuddyServiceException(bcr.Error));
         }
         else
         {
             tcs.TrySetResult(bcr.Result);
         }
     });
     return tcs.Task;
 }
示例#39
0
 /// <summary>
 /// Record runtime crash information for this app. This could be exceptions, errors or your own custom crash information.
 /// </summary>
 /// <param name="methodName">The method name or location where the error happend. This could also be a descriptive string of the error.</param>
 /// <param name="osVersion">The OS version of the device runnign this code. On some .NET platforms you can use System.Environment.OSVersion to get this information.</param>
 /// <param name="deviceType">The type of device running this app. On Windows Phone 7 for example you can use DeviceExtendedProperties to retrieve this information.</param>
 /// <param name="user">The user that's registering this device information.</param>
 /// <param name="stackTrace">The optional stack trace of where the error happened.</param>
 /// <param name="appVersion">The optional version of this application.</param>
 /// <param name="latitude">The optional latitude where this report was submitted.</param>
 /// <param name="longitude">The optional longiture where this report was submitted.</param>
 /// <param name="metadata">An optional application specific metadata string to include with the report.</param>
 /// <returns>A Task&lt;Boolean&gt;that can be used to monitor progress on this call.</returns>
 public System.Threading.Tasks.Task<Boolean> RecordCrashAsync( string methodName, string osVersion, string deviceType, Buddy.AuthenticatedUser user, string stackTrace = "", string appVersion = "1.0", double latitude = 0, double longitude = 0, string metadata = "")
 {
     var tcs = new System.Threading.Tasks.TaskCompletionSource<Boolean>();
     RecordCrashInternal(methodName, osVersion, deviceType, user, stackTrace, appVersion, latitude, longitude, metadata, (bcr) =>
     {
         if (bcr.Error != BuddyServiceClient.BuddyError.None)
         {
             tcs.TrySetException(new BuddyServiceException(bcr.Error));
         }
         else
         {
             tcs.TrySetResult(bcr.Result);
         }
     });
     return tcs.Task;
 }
 /// <summary>
 /// Find the public profile of a user from their unique User ID. This method can be used to find any user associated with this Application.
 /// </summary>
 /// <param name="id">The ID of the user, must be bigger than 0.</param><exception cref="T:Buddy.BuddyServiceException">With value: InvalidUserId, when the user ID doesn't exist in the system.</exception>
 /// <returns>A Task&lt;User&gt;that can be used to monitor progress on this call.</returns>
 public System.Threading.Tasks.Task<User> FindUserAsync(int id)
 {
     var tcs = new System.Threading.Tasks.TaskCompletionSource<User>();
     FindUserInternal(id, (bcr) =>
     {
         if (bcr.Error != BuddyServiceClient.BuddyError.None)
         {
             tcs.TrySetException(new BuddyServiceException(bcr.Error));
         }
         else
         {
             tcs.TrySetResult(bcr.Result);
         }
     });
     return tcs.Task;
 }
示例#41
0
  /// <summary>
  /// Get a metadata item with a key. The key can't be null or an empty string.
  /// </summary>
  /// <param name="key">The key to use to reference the metadata item.</param><exception cref="T:System.ArgumentException">When key is null or empty.</exception>
  /// <returns>A Task&lt;MetadataItem&gt;that can be used to monitor progress on this call.</returns>
 public System.Threading.Tasks.Task<MetadataItem> GetAsync( string key)
  {
      var tcs = new System.Threading.Tasks.TaskCompletionSource<MetadataItem>();
      this.GetInternal(key, (bcr) =>
      {
          if (bcr.Error != BuddyServiceClient.BuddyError.None)
          {
              tcs.TrySetException(new BuddyServiceException(bcr.Error));
          }
          else
          {
              tcs.TrySetResult(bcr.Result);
          }
      });
      return tcs.Task;
  }
示例#42
0
  /// <summary>
  /// Search for metadata items in this user. Note that this method will only find user-level metadata items.
  /// </summary>
  /// <param name="searchDistanceMeters">The distance in meters from the latitude and longitude to search in. To ignore this distance pass in 40075000 (the circumferance of the earth).</param>
  /// <param name="latitude">The latitude from where the saerch will start.</param>
  /// <param name="longitude">The longitude from where the saerch will start.</param>
  /// <param name="numberOfResults">Optionally limit the number of returned metadata items.</param>
  /// <param name="withKey">Optionally search for items with a specific key. The value of this parameter is treated as a wildcard.</param>
  /// <param name="withValue">Optionally search for items with a specific value. The value of this parameter is treated as a wildcard.</param>
  /// <param name="updatedMinutesAgo">Optionally return only items that were updated some minutes ago.</param>
  /// <param name="searchAsFloat">Optionally treat all metadata values as floats. Useful for min/max searches.</param>
  /// <param name="sortAscending">Optionally sort the results ascending.</param>
  /// <param name="disableCache">Optionally disable cache searches.</param>
  /// <returns>A Task&lt;IDictionary&lt;String,MetadataItem&gt; &gt;that can be used to monitor progress on this call.</returns>
 public System.Threading.Tasks.Task<IDictionary<String, MetadataItem>> FindAsync( int searchDistanceMeters, double latitude, double longitude, int numberOfResults = 10, string withKey = "", string withValue = "", int updatedMinutesAgo = -1, bool searchAsFloat = false, bool sortAscending = false, bool disableCache = false)
  {
      var tcs = new System.Threading.Tasks.TaskCompletionSource<IDictionary<String, MetadataItem>>();
      this.FindInternal(searchDistanceMeters, latitude, longitude, numberOfResults, withKey, withValue, updatedMinutesAgo, searchAsFloat, sortAscending, disableCache, (bcr) =>
      {
          if (bcr.Error != BuddyServiceClient.BuddyError.None)
          {
              tcs.TrySetException(new BuddyServiceException(bcr.Error));
          }
          else
          {
              tcs.TrySetResult(bcr.Result);
          }
      });
      return tcs.Task;
  }
示例#43
0
  /// <summary>
  /// Get all the metadata items for this user. Note that this can be a very expensive method, try to retrieve specific items if possible
  /// or do a search.
  /// </summary>
  /// <returns>A Task&lt;IDictionary&lt;String,MetadataItem&gt; &gt;that can be used to monitor progress on this call.</returns>
 public System.Threading.Tasks.Task<IDictionary<String, MetadataItem>> GetAllAsync()
  {
      var tcs = new System.Threading.Tasks.TaskCompletionSource<IDictionary<String, MetadataItem>>();
      this.GetAllInternal((bcr) =>
      {
          if (bcr.Error != BuddyServiceClient.BuddyError.None)
          {
              tcs.TrySetException(new BuddyServiceException(bcr.Error));
          }
          else
          {
              tcs.TrySetResult(bcr.Result);
          }
      });
      return tcs.Task;
  }
示例#44
0
        public ConnectionMultiplexer GetConnection()
        {
            if (_connection == null || !_connection.IsConnected)
            {
                lock (_connectionLock)
                {
                    if (_connection != null && _connection.IsConnected)
                    {
                        return(_connection);
                    }
                    if (_connection != null)
                    {
                        _connection.Close(false);
                        _connection.Dispose();
                        _connection = null;
                    }

                    var  tryCount = 0;
                    bool allowRetry;
                    do
                    {
                        allowRetry = false;
                        try
                        {
                            var sw      = Stopwatch.StartNew();
                            var innerSw = Stopwatch.StartNew();
                            try
                            {
                                // Sometimes ConnectionMultiplexer.Connect is failed and issue does not solved https://github.com/StackExchange/StackExchange.Redis/issues/42
                                // I've created manualy Connect and control timeout.
                                // I recommend set connectTimeout from 1000 to 5000. (configure your network latency)
                                var tcs           = new System.Threading.Tasks.TaskCompletionSource <ConnectionMultiplexer>();
                                var connectThread = new Thread(_ =>
                                {
                                    try
                                    {
                                        var connTask = ConnectionMultiplexer.ConnectAsync(_configuration, _connectionMultiplexerLog)
                                                       .ContinueWith(x =>
                                        {
                                            innerSw.Stop();
                                            if (x.IsCompleted)
                                            {
                                                if (!tcs.TrySetResult(x.Result))
                                                {
                                                    // already faulted
                                                    x.Result.Close(false);
                                                    x.Result.Dispose();
                                                }
                                            }
                                        });
                                        if (!connTask.Wait(this._configuration.ConnectTimeout))
                                        {
                                            tcs.TrySetException(new TimeoutException("Redis Connect Timeout. Elapsed:" + sw.Elapsed.TotalMilliseconds + "ms"));
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        tcs.TrySetException(ex);
                                    }
                                });
                                connectThread.Start();

                                _connection = tcs.Task.GetAwaiter().GetResult();
                                _connection.IncludeDetailInExceptions = true;
                                sw.Stop();
                            }
                            catch (Exception)
                            {
                                sw.Stop();
                                _connection = null;
                            }
                        }
                        catch (TimeoutException)
                        {
                            tryCount++;
                            allowRetry = true;
                        }
                    } while (_connection == null && allowRetry);
                }
            }

            return(_connection);
        }
示例#45
0
  /// <summary>
  /// Set metadata item values for keys. You can additionally add a latitude and longitude coordinate to record the location
  /// from where these items were set, or tag all items with a custom tag. 
  /// The item doesn't have to exist to be set, this method acts as an Add method in cases where the item doesn't exist.
  /// </summary>
  /// <param name="keys">The keys of the metadata items, can't be null or empty.</param>
  /// <param name="values">The values of the metadata items, can't be null or empty.</param>
  /// <param name="latitude">The optional latitude of the metadata items.</param>
  /// <param name="longitude">The optional longitude of the metadata items.</param>
  /// <param name="appTag">The optional application tag for these items.</param><exception cref="T:System.ArgumentException">When any key is null or empty.</exception><exception cref="T:System.ArgumentNullException">When any value is or empty.</exception>
  /// <returns>A Task&lt;Boolean&gt;that can be used to monitor progress on this call.</returns>
 public System.Threading.Tasks.Task<Boolean> BatchSetAsync( string keys, string values, double latitude = 0, double longitude = 0, string appTag = "")
  {
      var tcs = new System.Threading.Tasks.TaskCompletionSource<Boolean>();
      this.BatchSetInternal(keys, values, latitude, longitude, appTag, (bcr) =>
      {
          if (bcr.Error != BuddyServiceClient.BuddyError.None)
          {
              tcs.TrySetException(new BuddyServiceException(bcr.Error));
          }
          else
          {
              tcs.TrySetResult(bcr.Result);
          }
      });
      return tcs.Task;
  }
示例#46
0
    /// <summary>
 /// Gets a list of profile photos for this user.
 /// </summary>
 /// <returns>A Task&lt;IEnumerable&lt;PicturePublic&gt; &gt;that can be used to monitor progress on this call.</returns>
 public System.Threading.Tasks.Task<IEnumerable<PicturePublic>> GetProfilePhotosAsync()
 {
     var tcs = new System.Threading.Tasks.TaskCompletionSource<IEnumerable<PicturePublic>>();
     GetProfilePhotosInternal((bcr) =>
     {
         if (bcr.Error != BuddyServiceClient.BuddyError.None)
         {
             tcs.TrySetException(new BuddyServiceException(bcr.Error));
         }
         else
         {
             tcs.TrySetResult(bcr.Result);
         }
     });
     return tcs.Task;
 }
示例#47
0
  /// <summary>
  /// This method returns the sum of a set of metadata items that correspond to a certain key wildcard. Note that the values of these items
  /// need to be numbers or floats, otherwise this method will fail.
  /// Unlike the 'Sum' method this method can take a list of keys separated by semicolons and will return a list of sums for all of those keys.
  /// </summary>
  /// <param name="forKeys">The key to use to filter the items that need to be summed. Is always treated as a wildcard.</param>
  /// <param name="withinDistance">Optionally sum only items within a certain number of meters from lat/long.</param>
  /// <param name="latitude">Optionally provide a latitude where the search can be started from.</param>
  /// <param name="longitude">Optionally provide a longitude where the search can be started from.</param>
  /// <param name="updatedMinutesAgo">Optionally sum only on items that have been update a number of minutes ago.</param>
  /// <param name="withAppTag">Optionally sum only items that have a certain application tag.</param>
  /// <returns>A Task&lt;IEnumerable&lt;MetadataSum&gt; &gt;that can be used to monitor progress on this call.</returns>
 public System.Threading.Tasks.Task<IEnumerable<MetadataSum>> BatchSumAsync( string forKeys, string withinDistance = "-1", double latitude = -1, double longitude = -1, int updatedMinutesAgo = -1, string withAppTag = "")
  {
      var tcs = new System.Threading.Tasks.TaskCompletionSource<IEnumerable<MetadataSum>>();
      this.BatchSumInternal(forKeys, withinDistance, latitude, longitude, updatedMinutesAgo, withAppTag, (bcr) =>
      {
          if (bcr.Error != BuddyServiceClient.BuddyError.None)
          {
              tcs.TrySetException(new BuddyServiceException(bcr.Error));
          }
          else
          {
              tcs.TrySetResult(bcr.Result);
          }
      });
      return tcs.Task;
  }
 /// <summary>
 /// Register a Windows device for notificatons with Buddy. The URL is the notifications channel link that provided by the platform. Most of the time
 /// you don't need to call this API directly, you can use ConfigurePushAsync instead which will configure everyting for you. Note that if you call this method,
 /// you are responsible to configure the device for push notifications.
 /// </summary>
 /// <param name="deviceUri">The device notification channel URI.</param>
 /// <param name="enableTile">Optionally enable tile notifications</param>
 /// <param name="enableRaw">Optionally enable raw notifications.</param>
 /// <param name="enableToast">Optionally enable toast notifications.</param>
 /// <param name="groupName">Register this device as part of a group, so that you can send the whole group messages.</param>
 /// <returns>A Task&lt;Boolean&gt;that can be used to monitor progress on this call.</returns>
 public System.Threading.Tasks.Task<Boolean> RegisterDeviceAsync(string deviceUri, bool enableTile = true, bool enableRaw = true, bool enableToast = true, string groupName = "")
 {
     var tcs = new System.Threading.Tasks.TaskCompletionSource<Boolean>();
     RegisterDeviceInternal(deviceUri, enableTile, enableRaw, enableToast, groupName, (bcr) =>
     {
         if (bcr.Error != BuddyServiceClient.BuddyError.None)
         {
             tcs.TrySetException(new BuddyServiceException(bcr.Error));
         }
         else
         {
             tcs.TrySetResult(bcr.Result);
         }
     });
     return tcs.Task;
 }
示例#49
0
 /// <summary>
 /// Add a new picture to this album. Note that this method internally does two web-service calls, and the IAsyncResult object
 /// returned is only valid for the first one.
 /// </summary>
 /// <param name="photoStream">A stream containing the photo's contents..</param>
 /// <param name="comment">An optional comment for this picture.</param>
 /// <param name="latitude">An optional latitude for the picture.</param>
 /// <param name="longitude">An optional longitude for the picture.</param>
 /// <param name="appTag">An optional application tag.</param>
 /// <param name="watermarkmessage">An optional message to watermark the image with.</param>
 /// <returns>A Task&lt;Picture&gt;that can be used to monitor progress on this call.</returns>
 public System.Threading.Tasks.Task<Picture> AddPictureWithWatermarkAsync(Stream photoStream, string comment = "", double latitude = 0, double longitude = 0, string appTag = "", string watermarkmessage = "")
 {
     var tcs = new System.Threading.Tasks.TaskCompletionSource<Picture>();
     AddPictureWithWatermarkInternal(photoStream, comment, latitude, longitude, appTag, watermarkmessage, (bcr) =>
     {
         if (bcr.Error != BuddyServiceClient.BuddyError.None)
         {
             tcs.TrySetException(new BuddyServiceException(bcr.Error));
         }
         else
         {
             tcs.TrySetResult(bcr.Result);
         }
     });
     return tcs.Task;
 }
 /// <summary>
 /// Get a paged list of registered devices for this Application. This list can then be used to iterate over the devices and send each user a push notification.
 /// </summary>
 /// <param name="forGroup">Optionally filter only devices in a certain group.</param>
 /// <param name="pageSize">Set the number of devices that will be returned for each call of this method.</param>
 /// <param name="currentPage">Set the current page.</param>
 /// <returns>A Task&lt;IEnumerable&lt;RegisteredDevice&gt; &gt;that can be used to monitor progress on this call.</returns>
 public System.Threading.Tasks.Task<IEnumerable<RegisteredDevice>> GetRegisteredDevicesAsync(string forGroup = "", int pageSize = 10, int currentPage = 1)
 {
     var tcs = new System.Threading.Tasks.TaskCompletionSource<IEnumerable<RegisteredDevice>>();
     GetRegisteredDevicesInternal(forGroup, pageSize, currentPage, (bcr) =>
     {
         if (bcr.Error != BuddyServiceClient.BuddyError.None)
         {
             tcs.TrySetException(new BuddyServiceException(bcr.Error));
         }
         else
         {
             tcs.TrySetResult(bcr.Result);
         }
     });
     return tcs.Task;
 }
 /// <summary>
 /// Send a image tile to a windows phone device. The tile is represented by a image URL, you can take a look at the Windows phone docs for image dimensions and formats.
 /// </summary>
 /// <param name="imageUri">The URL of the tile image.</param>
 /// <param name="senderUserId">The ID of the user that sent the notification.</param>
 /// <param name="messageCount">The message count for this tile.</param>
 /// <param name="messageTitle">The message title for the tile.</param>
 /// <param name="deliverAfter">Schedule the message to be delivered after a certain date.</param>
 /// <param name="groupName">Send messages to an entire group of users, not just a one.</param>
 /// <returns>A Task&lt;Boolean&gt;that can be used to monitor progress on this call.</returns>
 public  System.Threading.Tasks.Task<Boolean> SendTileAsync(string imageUri, int senderUserId, int messageCount = -1, string messageTitle = "", System.DateTime deliverAfter = default(DateTime), string groupName = "")
 {
     var tcs = new System.Threading.Tasks.TaskCompletionSource<Boolean>();
     SendTileInternal(imageUri, senderUserId, messageCount, messageTitle, deliverAfter, groupName, (bcr) =>
     {
         if (bcr.Error != BuddyServiceClient.BuddyError.None)
         {
             tcs.TrySetException(new BuddyServiceException(bcr.Error));
         }
         else
         {
             tcs.TrySetResult(bcr.Result);
         }
     });
     return tcs.Task;
 }
 /// <summary>
 /// Send toast message to a windows phone device. If the app is active the user will recieve this message in the toast message callback. Otherwise the message
 /// appears as a notification on top of the screen. Clicking it will launch the app.
 /// </summary>
 /// <param name="toastTitle">The title of the toast message/</param>
 /// <param name="toastSubtitle">The subtitle of the toast message.</param>
 /// <param name="toastParameter">An optional parameter for the toast message.</param>
 /// <param name="senderUserId">The ID of the user that sent the notification.</param>
 /// <param name="deliverAfter">Schedule the message to be delivered after a certain date.</param>
 /// <param name="groupName">Send messages to an entire group of users, not just a one.</param>
 /// <returns>A Task&lt;Boolean&gt;that can be used to monitor progress on this call.</returns>
 public System.Threading.Tasks.Task<Boolean> SendToastMessageAsync(string toastTitle, string toastSubtitle, int senderUserId, string toastParameter = "", System.DateTime deliverAfter = default(DateTime), string groupName = "")
 {
     var tcs = new System.Threading.Tasks.TaskCompletionSource<Boolean>();
     SendToastMessageInternal(toastTitle, toastSubtitle, senderUserId, toastParameter, deliverAfter, groupName, (bcr) =>
     {
         if (bcr.Error != BuddyServiceClient.BuddyError.None)
         {
             tcs.TrySetException(new BuddyServiceException(bcr.Error));
         }
         else
         {
             tcs.TrySetResult(bcr.Result);
         }
     });
     return tcs.Task;
 }
示例#53
0
  /// <summary>
  /// Updates one or more fields of an existing Player object which was previously created.
  /// </summary>
  /// <param name="name">The name of the new player.</param>
  /// <param name="board">An optional name of a "Board" for the game. Used for grouping scores together either by user group, levels, or some other method relevant to the game. Although optional, a value is recommended such as "Default" for use in later searches of scores. If no board is to be stored, then pass in null or leave empty.</param>
  /// <param name="rank">An optional ranking to associate with the score. Can be any string ie: descriptions of achievements, ranking strings like "excellent", etc. Pass in null or an empty string if you do not wish to store a rank</param>
  /// <param name="latitude">The latitude of the location where the Player object is being updated.</param>
  /// <param name="longitude">The longitude of the location where the Player object is being updated. </param>
  /// <param name="appTag">Optional metadata to store with the Player object. ie: a list of players, game state, etc. Leave empty or set to null if there is no data to store with the score.</param>
  /// <returns>A Task&lt;Boolean&gt;that can be used to monitor progress on this call.</returns>
 public System.Threading.Tasks.Task<Boolean> UpdateAsync( string name, string board = "", string rank = "", double latitude = 0, double longitude = 0, string appTag = "")
  {
      var tcs = new System.Threading.Tasks.TaskCompletionSource<Boolean>();
      this.UpdateInternal(name, board, rank, latitude, longitude, appTag, (bcr) =>
      {
          if (bcr.Error != BuddyServiceClient.BuddyError.None)
          {
              tcs.TrySetException(new BuddyServiceException(bcr.Error));
          }
          else
          {
              tcs.TrySetResult(bcr.Result);
          }
      });
      return tcs.Task;
  }
示例#54
0
        /// <summary>
        /// Configure this Windows Phone device for push notifications
        /// </summary>
        /// <param name="channelName"></param>
        /// <param name="enableTiles"></param>
        /// <param name="enableToastMessages"></param>
        /// <param name="groupName"></param>
        /// <param name="allowedDomains"></param>
        /// <param name="rawMessageCallback"></param>
        /// <param name="toastMessageCallback"></param>
        public System.Threading.Tasks.Task <Boolean> ConfigurePushAsync(bool enableTiles, bool enableToastMessages, string groupName = "",
                                                                        List <string> allowedDomains = null, Action <string> rawMessageCallback = null, Action <IDictionary <string, string> > toastMessageCallback = null, string channelName = null)
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource <Boolean>();

            Action <bool, Exception> finish = (result, ex) =>
            {
                if (ex != null)
                {
                    tcs.TrySetException(ex);
                }
                else
                {
                    tcs.TrySetResult(result);
                }
            };

            if (allowedDomains == null)
            {
                allowedDomains = new List <string>();
            }
            allowedDomains.Add("http://buddyplatform.s3.amazonaws.com/");

            channelName = this.GetChannelName(channelName);

            HttpNotificationChannel channel = null;
            bool done = false;

            if ((channel = HttpNotificationChannel.Find(channelName)) == null)
            {
                channel = new HttpNotificationChannel(channelName, "www.buddy.com");
                if (channel == null)
                {
                    Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        finish(false, new Exception("Couldn't create HttpNotificationChannel."));
                    });

                    done = true;
                }
                else
                {
                    channel.Open();
                }
            }

            if (!done && rawMessageCallback != null)
            {
                channel.HttpNotificationReceived += (s, ev) =>
                {
                    StreamReader reader = new StreamReader(ev.Notification.Body);

                    Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        rawMessageCallback(reader.ReadToEnd());
                    });
                }
            }
            ;


            if (!done && toastMessageCallback != null)
            {
                channel.ShellToastNotificationReceived += (s, ev) =>
                {
                    Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        toastMessageCallback(ev.Collection);
                    });
                }
            }
            ;

            Action <HttpNotificationChannel> registerUri = (newChannel) =>
            {
                if (enableTiles)
                {
                    BindTile(newChannel, allowedDomains);
                }

                if (enableToastMessages)
                {
                    BindToast(newChannel);
                }

                this.RegisterDeviceInternal(newChannel.ChannelUri.ToString(), enableTiles, rawMessageCallback != null, enableToastMessages, groupName, (bcr) =>
                {
                    finish(bcr.Result, bcr.Error == BuddyError.None ? null : new BuddyServiceException(bcr.Error.ToString()));
                });
            };

            if (!done)
            {
                channel.ChannelUriUpdated += (s, ev) =>
                {
                    registerUri(channel);
                };

                if (channel.ChannelUri != null)
                {
                    registerUri(channel);
                }
            }
            return(tcs.Task);
        }
示例#55
0
  /// <summary>
  /// Get all the player info for this user.
  /// </summary>
  /// <returns>A Task&lt;GamePlayer&gt;that can be used to monitor progress on this call.</returns>
 public System.Threading.Tasks.Task<GamePlayer> GetInfoAsync()
  {
      var tcs = new System.Threading.Tasks.TaskCompletionSource<GamePlayer>();
      this.GetInfoInternal((bcr) =>
      {
          if (bcr.Error != BuddyServiceClient.BuddyError.None)
          {
              tcs.TrySetException(new BuddyServiceException(bcr.Error));
          }
          else
          {
              tcs.TrySetResult(bcr.Result);
          }
      });
      return tcs.Task;
  }
示例#56
0
  /// <summary>
  /// Searches for Player objects stored in the Buddy system. Searches can optionally be performed based on location.
  /// </summary>
  /// <param name="searchDistanceInMeters">The radius (in meters) around the specified location in which to look for locations. Pass in -1 to ignore this field.  </param>
  /// <param name="latitude">The latitude of the location around which to search for locations within the specified SearchDistance.   </param>
  /// <param name="longitude">The longitude of the location around which to search for locations within the specified SearchDistance. </param>
  /// <param name="recordLimit">The maximum number of search results to return or -1 to return all search results.    </param>
  /// <param name="boardName">Searches for scores which contain the specified board. Leave empty or pass in null if no board filter is to be used.    </param>
  /// <param name="onlyForLastNumberOfDays">The number of days into the past for which to look for scores. ie: passing in 5 will filter scores to include those which were added/updated on or after 5 days ago. Pass in -1 to ignore this filter.    </param>
  /// <param name="minimumScore">The minimum score value to search for. Pass in -1 to ignore this filter. </param>
  /// <param name="appTag">Searches for scores with the specified ApplicationTag stored with them. Leave empty or pass in null to ignore this filter. </param>
  /// <param name="rank">Optionally search for a player rank.</param>
  /// <returns>A Task&lt;IEnumerable&lt;GamePlayer&gt; &gt;that can be used to monitor progress on this call.</returns>
 public System.Threading.Tasks.Task<IEnumerable<GamePlayer>> FindAsync( int searchDistanceInMeters = -1, double latitude = 0, double longitude = 0, int recordLimit = 100, string boardName = "", int onlyForLastNumberOfDays = -1, int minimumScore = -1, string appTag = "", string rank = "")
  {
      var tcs = new System.Threading.Tasks.TaskCompletionSource<IEnumerable<GamePlayer>>();
      this.FindInternal(searchDistanceInMeters, latitude, longitude, recordLimit, boardName, onlyForLastNumberOfDays, minimumScore, appTag, rank, (bcr) =>
      {
          if (bcr.Error != BuddyServiceClient.BuddyError.None)
          {
              tcs.TrySetException(new BuddyServiceException(bcr.Error));
          }
          else
          {
              tcs.TrySetResult(bcr.Result);
          }
      });
      return tcs.Task;
  }
示例#57
0
        public System.Threading.Tasks.Task<HttpWebHelperAsyncResult> ExecuteTaskAsync(IHttpWebRequest httpWebRequest, Stream requestBody, object state)
        {
            var tcs = new System.Threading.Tasks.TaskCompletionSource<HttpWebHelperAsyncResult>(state);

            try
            {
                ExecuteAsync(httpWebRequest, requestBody,
                             ar =>
                             {
                                 var asyncResult = (HttpWebHelperAsyncResult)ar;
                                 if (asyncResult.IsCancelled) tcs.TrySetCanceled();
                                 if (asyncResult.Exception != null) tcs.TrySetException(asyncResult.Exception);
                                 else tcs.TrySetResult(asyncResult);
                             }, state);

            }
            catch (Exception ex)
            {
                tcs.TrySetException(ex);
            }

            return tcs.Task;
        }
示例#58
0
 /// <summary>
 /// Get a photo album by its name. Note that there can be more than one album with the same name. This method will only return the first one.
 /// Call PhotoAlbums.All to get all the albums.
 /// </summary>
 /// <param name="albumName">The name of the albul to retrieve. Can't be null or empty.</param>
 /// <returns>A Task&lt;PhotoAlbum&gt;that can be used to monitor progress on this call.</returns>
 public System.Threading.Tasks.Task<PhotoAlbum> GetAsync( string albumName)
 {
     var tcs = new System.Threading.Tasks.TaskCompletionSource<PhotoAlbum>();
     GetInternal(albumName, (bcr) =>
     {
         if (bcr.Error != BuddyServiceClient.BuddyError.None)
         {
             tcs.TrySetException(new BuddyServiceException(bcr.Error));
         }
         else
         {
             tcs.TrySetResult(bcr.Result);
         }
     });
     return tcs.Task;
 }