15 domande
ComputerVisionClient Microsoft.azure.cognitiveservices.vision.computervision
Luca Tassi
0
Punti di reputazione
I'm having issues when calling my computer vision endpoint multiple times concurrently.
I get the following error:
ERROR: System.NullReferenceException: Object reference not set to an instance of an object.
at System.Net.Http.HttpConnection.WriteAsciiString(String s)
at System.Net.Http.HttpConnection.WriteHeaderCollection(HttpHeaders headers, String cookiesFromContainer)
at System.Net.Http.HttpConnection.WriteHeaders(HttpRequestMessage request)
at System.Net.Http.HttpConnection.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpConnection.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.DiagnosticsHandler.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.<SendCoreAsync>g__Core|4_0(HttpRequestMessage request, Boolean useAsync, CancellationToken cancellationToken)
at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.<SendCoreAsync>g__Core|4_0(HttpRequestMessage request, Boolean useAsync, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
at Microsoft.Azure.CognitiveServices.Vision.ComputerVision.ComputerVisionClient.ReadInStreamWithHttpMessagesAsync(Stream image, String language, IList1 pages, String modelVersion, String readingOrder, Dictionary2 customHeaders, CancellationToken cancellationToken)
at Microsoft.Azure.CognitiveServices.Vision.ComputerVision.ComputerVisionClientExtensions.ReadInStreamAsync(IComputerVisionClient operations, Stream image, String language, IList1 pages, String modelVersion, String readingOrder, CancellationToken cancellationToken).
I thought the issue was the initialization of my http client in my .net core 9 project but now after all the improvement I developed to correctly inject the httpclient as follows
service.AddHttpClient<IHttpCaller, HttpCaller>()
.ConfigurePrimaryHttpMessageHandler(() =>
{
var handler = new SocketsHttpHandler
{
// Explicitly set connection lifetime to refresh regularly.
PooledConnectionLifetime = TimeSpan.FromMinutes(10),
// Explicit idle connection management.
PooledConnectionIdleTimeout = TimeSpan.FromMinutes(5),
// Enable TCP KeepAlive to detect broken connections earlier
KeepAlivePingPolicy = HttpKeepAlivePingPolicy.Always,
KeepAlivePingDelay = TimeSpan.FromSeconds(30),
KeepAlivePingTimeout = TimeSpan.FromSeconds(10),
// Configure proxy if needed.
Proxy = proxy != null && !string.IsNullOrWhiteSpace(proxy.Url)
? new WebProxy(proxy.Url, true)
{
Credentials = !string.IsNullOrWhiteSpace(proxy.Username)
? new NetworkCredential(proxy.Username, proxy.Password, proxy.Domain)
: null
}
: null,
UseProxy = proxy != null && !string.IsNullOrWhiteSpace(proxy.Url),
// Control maximum simultaneous connections per server if necessary.
MaxConnectionsPerServer = 1000,
// Add connect timeout for faster failure detection
ConnectTimeout = TimeSpan.FromSeconds(30),
};
return handler;
})
.SetHandlerLifetime(Timeout.InfiniteTimeSpan)
.ConfigureHttpClient(client =>
{
client.Timeout = TimeSpan.FromMinutes(10);
client.DefaultRequestVersion = HttpVersion.Version20;
client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrLower;
// Add connection establishment
client.DefaultRequestHeaders.ConnectionClose = false;
});
the error is still happening.
This is the code calling the ocr computer vision
using Microsoft.Azure.CognitiveServices.Vision.ComputerVision;
using Microsoft.Azure.CognitiveServices.Vision.ComputerVision.Models;
using PolarisAI.Common.Contracts.Building;
using PolarisAI.Common.Contracts.Reading;
using PolarisAI.ImageReader.App;
using PolarisAI.ImageReader.Conversion;
using PolarisAI.ImageReader.OutputReaders;
namespace PolarisAI.ImageReader
{
/// <summary>
/// Provides OCR (Optical Character Recognition) functionality using Azure Cognitive Services Computer Vision API.
/// Handles document conversion and communication with Azure OCR endpoints.
/// </summary>
public class AzureOcrReader : IOcrReader
{
/// <summary>
/// Parameters for configuring the AzureOcrReader.
/// </summary>
/// <param name="IsConversionToImageDisabled">Disables conversion to image if true.</param>
/// <param name="TiffConversionResolution">Resolution to use for TIFF conversion.</param>
public record Parameters(bool IsConversionToImageDisabled, int TiffConversionResolution = 150);
private readonly HttpClient _httpClient;
private readonly string? _ocrEndpoint;
private readonly string? _key;
private const int MaxPollingIterations = 300;
private const int PollingInterval = 2000;
/// <summary>
/// Gets the TIFF conversion resolution.
/// </summary>
public int TiffConversionResolution { get; }
/// <summary>
/// Gets a value indicating whether conversion to image is disabled.
/// </summary>
public bool IsConversionToImageDisabledDefault { get; }
/// <summary>
/// Initializes a new instance of the <see cref="AzureOcrReader"/> class.
/// </summary>
/// <param name="httpClient">The HTTP client to use for requests.</param>
/// <param name="description">A description for the reader instance.</param>
/// <param name="ocrEndpoint">The Azure OCR endpoint URL.</param>
/// <param name="key">The Azure OCR API key.</param>
/// <param name="parameters">Parameters for conversion and resolution.</param>
public AzureOcrReader(HttpClient httpClient, string description, string? ocrEndpoint, string? key, Parameters parameters)
{
_httpClient = httpClient;
_ocrEndpoint = ocrEndpoint;
_key = key;
IsConversionToImageDisabledDefault = parameters.IsConversionToImageDisabled;
TiffConversionResolution = parameters.TiffConversionResolution;
}
/// <summary>
/// Authenticates and creates a ComputerVisionClient for Azure OCR.
/// </summary>
/// <param name="httpClient">The HTTP client to use.</param>
/// <param name="key">The API key.</param>
/// <param name="ocrEndpoint">The endpoint URL.</param>
/// <returns>A configured ComputerVisionClient instance.</returns>
private static ComputerVisionClient Authenticate(HttpClient httpClient, string key, string ocrEndpoint)
{
ComputerVisionClient client = new ComputerVisionClient(new ApiKeyServiceClientCredentials(key), httpClient, false) { Endpoint = ocrEndpoint };
return client;
}
/// <summary>
/// Reads a document asynchronously and performs OCR, optionally converting to image.
/// </summary>
/// <param name="documentName">The name of the document.</param>
/// <param name="buffer">The document content as a byte array.</param>
/// <param name="isConversionToImageDisabled">Optional override for image conversion.</param>
/// <returns>The OCR output result.</returns>
public async Task<IOcrOutput> ReadDocAsync(string documentName, byte[] buffer, bool? isConversionToImageDisabled = null)
{
var isConversionDisabled = isConversionToImageDisabled ?? IsConversionToImageDisabledDefault;
try
{
byte[] newBuffer = !isConversionDisabled ? FormatConverter.ToImage(documentName, buffer, PdfEvaluator.HasToBeConvertedToImage, TiffConversionResolution) : buffer;
return await ReadImageAsync(documentName, newBuffer);
}
catch (Exception e)
{
return OcrOutput.ReadingFailure(documentName, e.ToString());
}
}
/// <summary>
/// Logs the current parameters for the reader.
/// </summary>
/// <returns>A string representing the parameters.</returns>
public string LogParameters() => $"{nameof(IsConversionToImageDisabledDefault)}: {IsConversionToImageDisabledDefault}, {nameof(TiffConversionResolution)}: {TiffConversionResolution}";
/// <summary>
/// Reads an image asynchronously and performs OCR using Azure Computer Vision.
/// </summary>
/// <param name="documentName">The name of the document.</param>
/// <param name="buffer">The image content as a byte array.</param>
/// <returns>The OCR output result.</returns>
private async Task<IOcrOutput> ReadImageAsync(string documentName, byte[] buffer)
{
MemoryStream inputStream = new MemoryStream(buffer);
LogWriter logger = new LogWriter();
try
{
var key = _key ?? Environment.GetEnvironmentVariable(Constants.AzureOcrEnvKey) ?? throw new EmptyCredentialException($"Empty environment variable {nameof(Constants.AzureOcrEnvKey)}");
var url = _ocrEndpoint ?? Environment.GetEnvironmentVariable(Constants.AzureOcrEnvUrl) ?? throw new EmptyCredentialException($"Empty environment variable {nameof(Constants.AzureOcrEnvUrl)}");
using var client = Authenticate(_httpClient, key, url);
logger.LogStart(documentName, buffer, $"{nameof(IsConversionToImageDisabledDefault)}: {IsConversionToImageDisabledDefault}");
IReaderRawOutputStructure results = await CallOcrService(client, inputStream);
logger.LogSummary($"Ocr result: {results.Status}");
return new OcrOutput(results, logger.ToString());
}
catch (Exception e)
{
logger.LogError("ERROR: " + e);
return OcrOutput.ReadingFailure(documentName, logger.ToString());
}
finally
{
inputStream.Dispose();
}
}
/// <summary>
/// Calls the Azure OCR service and polls for the result.
/// </summary>
/// <param name="client">The ComputerVisionClient instance.</param>
/// <param name="inputStream">The input stream containing the image data.</param>
/// <returns>The raw OCR output structure.</returns>
private static async Task<IReaderRawOutputStructure> CallOcrService(ComputerVisionClient client, MemoryStream inputStream)
{
var textHeaders = await client.ReadInStreamAsync(inputStream);
// After the request, get the operation location (operation ID)
string operationLocation = textHeaders.OperationLocation;
await Task.Delay(PollingInterval);
// <snippet_extract_response>
// Retrieve the URI where the recognized text will be stored from the Operation-Location header.
// We only need the ID and not the full URL
const int numberOfCharsInOperationId = 36;
string operationId = operationLocation.Substring(operationLocation.Length - numberOfCharsInOperationId);
// Extract the text
int cyclesCounter = 0;
ReadOperationResult results;
do
{
results = await client.GetReadResultAsync(Guid.Parse(operationId));
await Task.Delay(PollingInterval);
cyclesCounter++;
} while ((results.Status == OperationStatusCodes.Running || results.Status == OperationStatusCodes.NotStarted) && cyclesCounter < MaxPollingIterations);
return new AzureRawOutputStructure(results);
}
}
}
Can you help me understand what could be the issue?
Thanks
Tecnologie per sviluppatori | C#
Accedi per rispondere