EK_AllDay
EK_AllDay

Reputation: 1115

WebApi Task An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full

I am using asp.net webapi I occasionally get this error when I make a http request to a Webapi endpoint that returns a Task

Within this response, I use an await to make sure that the thread doesn't close until all threads have completed their task.

Essentially I have a Post method:

 public async Task<HttpResponseMessage> PostHouse(SessionModal sessionModal)
 {
 // create database context
 // Create a new house object
 House h = new House();
 h.address= await GetFormattedAddress(sessionModal.location)

  //save database
 }
public async Task<FormattedAdress> GetFormattedAddress(DBGeography Location)
{
 var client = new HttpClient();
 // create URI 
var URI = new URi......
Stream respSream= await client.GetStreamAsync(URI) 
// Data Contract Serializer
// Create Formatted Address
FormatedAddress address =....
return address; 
 }

The code works for a while, but over time I begin to get the error response:

"An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full"

If I restart the server, the issue is temporarily relieved. If I am consistantly getting this error, however I attempt to POST,GET,Delete or PUT a different controller endpoint, it will work. But if I go back and attempt to post the endpoint PostHouse, I will still get the error.

Is it possible that the thread isn't being disposed thus, the port being used never gets freed?

EDIT

Here is my exact code that I am trying to fix. I attempted to use using(){} However I still get the error. I think there is something am forgetting to dispose of. Pretty much I am getting a image from a Post, than I send it to Blob storage. If there is a better way of doing this, I wouldn't mind those suggestions either.

    public async Task<HttpResponseMessage> Post()
    {
        var result = new HttpResponseMessage(HttpStatusCode.OK);
        if (Request.Content.IsMimeMultipartContent())
        { try{
           await Request.Content.ReadAsMultipartAsync<MultipartMemoryStreamProvider>(new MultipartMemoryStreamProvider()).ContinueWith((task) =>
            {

                MultipartMemoryStreamProvider provider = task.Result;
                foreach (HttpContent content in provider.Contents)
                {
                    using (Stream stream = content.ReadAsStreamAsync().Result) { 
                    Image image = Image.FromStream(stream);
                    var testName = content.Headers.ContentDisposition.Name;
                    String[] header = (String[])Request.Headers.GetValues("userId");
                    int userId = Int32.Parse(header[0]);
                    using (var db = new studytree_dbEntities())
                    {
                        Person user = db.People.Find(userId);


                        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
         ConfigurationManager.ConnectionStrings["StorageConnectionString"].ConnectionString);

                        //CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
                        //  CloudConfigurationManager.GetSetting("StorageConnectionString"));
                        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
                        // Retrieve a reference to a container. 
                        CloudBlobContainer container = blobClient.GetContainerReference("profilepic");

                        // Create the container if it doesn't already exist.
                        container.CreateIfNotExists();
                        container.SetPermissions(new BlobContainerPermissions
                        {
                            PublicAccess =
                                BlobContainerPublicAccessType.Blob
                        });

                        string uniqueBlobName = string.Format("image_{0}.png",
               header[0]);

                        CloudBlockBlob blob = container.GetBlockBlobReference(uniqueBlobName);
                        user.ProfilePhotoUri = blob.Uri.ToString();
                        user.Student.ProfilePhotoUri = blob.Uri.ToString();
                        user.Tutor.ProfilePhotoUri = blob.Uri.ToString();
                        using (var streamOut = new System.IO.MemoryStream())
                        {
                            image.Save(streamOut, ImageFormat.Png);
                            streamOut.Position = 0;

                            blob.UploadFromStream(streamOut);
                            db.SaveChanges();
                        }
                    }
                    }


                }

            });
                 }
                catch (Exception e)
                {

                 JObject m=   JObject.Parse(JsonConvert.SerializeObject(new {e.Message,e.InnerException}));
                    return Request.CreateResponse<JObject>(HttpStatusCode.InternalServerError,m);
                }

            return Request.CreateResponse(HttpStatusCode.OK);



        }

        else
        {
            throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted"));





        }

    }

Upvotes: 1

Views: 2584

Answers (1)

Aron
Aron

Reputation: 15772

You aren't disposing your Stream.

Try this

public async Task<FormattedAdress> GetFormattedAddress(DBGeography Location)
{
    using(var client = new HttpClient())
    {
        var URI = new URi......
        using(Stream respSream= await client.GetStreamAsync(URI))
        {
            FormatedAddress address =....
            return address; 
        }
    }
}

What is going on is that you are leaving your network streams open, and your computer has a limited number of connections it can make. By not disposing them you hold on to them. So future requests can't use those connections.

Upvotes: 3

Related Questions