C# httpclient在(n)条消息之后出现同步错误(端口耗尽?)

C# httpclient在(n)条消息之后出现同步错误(端口耗尽?),c#,azure,runtime-error,httpclient,azure-webjobs,C#,Azure,Runtime Error,Httpclient,Azure Webjobs,我有一个运行在Azure中的控制台Appwebjob,它调用同样运行在Azure中的API。控制台应用程序从csv文件发布消息。 当我在本地windows 10计算机上运行控制台应用程序,api在azure中运行时,它按预期工作,没有错误。 当我在Azure中运行控制台应用程序并在Azure中运行api时,它会处理大约980条消息,然后开始报告错误 错误: 发送请求时出错 无法连接到远程服务器 我相信,出于某种原因,当控制台应用程序在Azure中运行时,它正在耗尽端口,但我不知道如何解决这个问题

我有一个运行在Azure中的控制台Appwebjob,它调用同样运行在Azure中的API。控制台应用程序从csv文件发布消息。 当我在本地windows 10计算机上运行控制台应用程序,api在azure中运行时,它按预期工作,没有错误。 当我在Azure中运行控制台应用程序并在Azure中运行api时,它会处理大约980条消息,然后开始报告错误

错误:

发送请求时出错 无法连接到远程服务器 我相信,出于某种原因,当控制台应用程序在Azure中运行时,它正在耗尽端口,但我不知道如何解决这个问题。 我的文件有50000行,但如上所述,在问题到达之前,只有大约980行。 在另一端,api将接收到的消息发布到sql数据库和azure事件中心。 如何在PostAsJsonAsync完成后强制应用程序释放端口? 如何检查端口是否已释放,或者如何检查端口是否可用? 如果您知道任何其他原因,我可能会得到这些错误,请帮助

这是我的密码:

public async Task<string> PostMessageToAPI(string aMsg)
{
    HttpResponseMessage response = null;
    string strResponse = "";    
    try
    {
        using (var client = new HttpClient())
        {
            client.SetBearerToken("access token here");
            client.BaseAddress = new Uri("MyBaseUrl.com");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            using (response =  await client.PostAsJsonAsync("my/url/goes/here", anEvent.ToLower()))
            {
                if (response != null)
                {
                    if (response.StatusCode != HttpStatusCode.OK)
                    {
                        throw new HttpRequestException(response.ReasonPhrase);
                    }
                    else
                    {
                        return await response.Content.ReadAsStringAsync();
                    }
                }
            }
        }
    }
    catch (HttpRequestException ex)
    {       
        //  exception message states: "An error occurred while sending the request"
    }   
    return strResponse;           
}
Visual Studio 2015更新3 .net 4.5.1 Azure控制台应用程序计划:基本1小 Azure API应用程序计划:基本1小 请不要使用包装在using中的HttpClient。使用静态实例并共享它

public class MyClass()
{
private HttpClient client = null;
public MyClass(){
    client = new HttpClient();
    client.SetBearerToken("access token here");
    client.BaseAddress = new Uri("MyBaseUrl.com");
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

}
public async Task<string> PostMessageToAPI(string aMsg)
{
    HttpResponseMessage response = null;
    string strResponse = "";    
    try
    {
        using (var response =  await client.PostAsync("my/url/goes/here", new StringContent(aMsg, Encoding.UTF8, "application/json")))
        {
            if (response != null)
            {
                if (response.StatusCode != HttpStatusCode.OK)
                {
                    throw new HttpRequestException(response.ReasonPhrase);
                }
                else
                {
                    return await response.Content.ReadAsStringAsync();
                }
            }
        }

    }
    catch (HttpRequestException ex)
    {       
        //  exception message states: "An error occurred while sending the request"
    }   
    return strResponse;           
}
}
您甚至可以共享该类的同一个实例,关键是,每次重新创建并重新打开套接字都不是最佳选择,它最终会导致套接字耗尽,具体取决于您的调用吞吐量


PostMessageToAPI是从多线程环境调用的吗?它是从Azure WebJob调用的,因此可以调用多个实例,但这是由Azure管理的。但是,我只测试一个实例。远程服务器上有谁/什么?是否有可能该端的连接未正确断开?web作业中使用了哪种触发器?-时间/队列/水滴?原因是,如果队列您可以灵活设置可以/需要处理的消息数量,并且能够租用和释放锁,则说明:只有9种方法CancelPendingRequests、DeleteAsync、GetAsync、GetByteArrayAsync、GetStreamAsync、GetStringAsync、PostAsync、PutAsync和SendAsync。所有属性都不能保证线程安全。请确保您的PostAsJsonAsync扩展方法不使用该列表中未包含的任何方法,也不使用任何属性。很好!我只是移植了静态使用的代码,这就是端口耗尽的原因。嗨,Matias,问题是我正在为每个调用重新创建httpclient。我现在将同一个httpclient重新用于所有调用,问题就解决了。这基本上就是您在代码中描述的内容,所以谢谢。我已把你的答案标为解决办法。