我正在使用asp.net webapi
当我向返回任务的Webapi端点发出http请求时,偶尔会出现此错误
在此响应中,我使用await来确保线程在所有线程完成其任务之前不会关闭。
本质上,我有一个Post方法:
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;
}
该代码可以工作一段时间,但是随着时间的流逝,我开始得到错误响应:
"An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full"
如果重新启动服务器,该问题将暂时缓解。如果我总是遇到此错误,但是我尝试过POST,GET,Delete或PUT一个不同的 Controller 端点,则它将起作用。但是,如果我返回并尝试发布终结点PostHouse,我仍然会收到错误消息。
是否有可能没有因此而释放线程,使正在使用的端口永远不会被释放?
编辑
这是我要修复的确切代码。我尝试使用using(){},但是仍然出现错误。我认为有一些事情要忘记处理。我几乎是从Post获取图像,而不是将其发送到Blob存储。如果有更好的方法,我也不会介意那些建议。
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"));
}
}
最佳答案
您没有处置Stream
。
试试这个
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;
}
}
}
发生的情况是您将网络流保持打开状态,并且计算机只能建立有限数量的连接。通过不处置它们,您可以坚持下去。因此,将来的请求不能使用这些连接。
关于c# - WebApi任务由于系统缺少足够的缓冲区空间或队列已满,无法对套接字执行操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26421872/