0

I am using Amazon S3 sdk with .Net for a Xamarin project, and I need to check if an object exists in a bucket before doing something with it. I cannot use the Exists property on Amazon.S3.IO.S3FileInfo because I cannot use the Amazon.S3.IO namespace in my code for some reason. (using this would make life so much easier for me), so I am using the following code (which I got from the source code for S3FileInfo here)

        public bool PackageExistsOnS3(string bucket, string key)
        {
            bool bucketExists;
            return ExistsWithBucketCheck(out bucketExists, bucket, key);
        }

        private bool ExistsWithBucketCheck(out bool bucketExists, string bucket, string key)
        {
            bucketExists = true;
            try
            {
                var request = new GetObjectMetadataRequest
                {
                    BucketName = bucket,
                    Key = AWSS3Helper.EncodeKey(key)
                };
                ((Amazon.Runtime.Internal.IAmazonWebServiceRequest) request).AddBeforeRequestHandler(AWSS3Helper
                    .FileIORequestEventHandler);

                AmazonS3Client _client = new AmazonS3Client(_accessKey, _secretKey, _regionEndPoint);

                // If the object doesn't exist then a "NotFound" will be thrown
                // I DO NOT WANT TO USE THE METADATAASYNC VERSION HERE, I JUST WANT THE REGULAR VERSION BUT I CANNOT DO THAT
                _client.GetObjectMetadataAsync();
                //var test = _client.GetObjectMetadata;
                return true;
            }
            catch (AmazonS3Exception e)
            {
                if (string.Equals(e.ErrorCode, "NoSuchBucket"))
                {
                    bucketExists = false;
                    return false;
                }
                else if (string.Equals(e.ErrorCode, "NotFound"))
                {
                    return false;
                }

                throw;
            }

        }

The code for AWSS3Helper is as below:

    internal static class AWSS3Helper
    {
        internal static string EncodeKey(string key)
        {
            return key.Replace('\\', '/');
        }

        internal static string DecodeKey(string key)
        {
            return key.Replace('/', '\\');
        }

        internal static void FileIORequestEventHandler(object sender, RequestEventArgs args)
        {
            WebServiceRequestEventArgs wsArgs = args as WebServiceRequestEventArgs;
            if (wsArgs != null)
            {
                string currentUserAgent = wsArgs.Headers[AWSSDKUtils.UserAgentHeader];
                wsArgs.Headers[AWSSDKUtils.UserAgentHeader] = currentUserAgent + " FileIO";
            }
        }
    }

Anyone know how I can avoid using this Asynchronous function? It will prevent me from returning a boolean value, and if I have to return something I would need use Await wherever this function is used meaning I would need to make every function that uses it an async function and I would really love to avoid the complications that come with doing that.

Kikanye
  • 1,198
  • 1
  • 14
  • 33

1 Answers1

0

You can try to make your function async and use the await keyword before _client.GetObjectMetadataAsync(). If you dont do this, you get if the fuction is implememnted as async Task< T > a Task and not T in your case T is bool. For IO connections it is standard now to use async functions in Dotnet to prevent your application to stop and waiting for response.

https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/

Agredo
  • 131
  • 1
  • 10
  • Yh I know I can do this, I was just hoping there would be a way no to, but since this is being suggested as the standard, I think I will just do it that way – Kikanye Nov 21 '19 at 22:08
  • If you dont want to wait (single thread) you can use var x = Task.Run(T => _client.GetObjectMetadataAsync()); x.Wait(); This is not recommended and because it blocks your Application for the time waiting for a Response, you can put it in a parallel thread but the you have the same as using async and await :) – Agredo Nov 22 '19 at 13:55