c# - WebApi任务由于系统缺少足够的缓冲区空间或队列已满,无法对套接字执行操作

标签 c# sockets asp.net-web-api task

我正在使用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/

相关文章:

c# - 从客户端获取修改后的对象并将其与服务器上的原始对象组合

c++ - 服务器关闭并重新启动后客户端无法连接

linux - UDP 数据包到达 Linux 上的错误套接字

sockets - 将 ESP8266 连接到虚拟 IP 地址/网站

asp.net - 为什么 ASP.NET Web API 只允许 POST 方法使用一个参数?

c# - Azure CosmosDB Contains 方法不起作用

c# - 多选 WinForms 列表框的双向绑定(bind)?

c# - 是否可以通过 API 在 Dynamics CRM 中定义具有属性的新实体类型?

c# - 如何从 Web API post 返回一个新类型?

asp.net-web-api - 如何在Azure Service Fabric中的自托管Web API上配置SSL