Reputation: 1115
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
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