I builded a Azure Service Bus Message provider to run in linux CENTOS 7 with core 2.0. I'm using the packge "Microsoft.Azure.ServiceBus 3.1.0". But when I receive
five hundred thousand(500 000) or more messages, the "RegisterMessageHandler" stop even with many active messages to read, does't receive anymore. I have five threads, "MaxConcurrentCall" with one hundred, Prefechcount 100 and "MaxAutoRenewDuration" in five minutes.
This method use "RegisterMessageHandler" to keep reading subscription continuously.
public async Task RecebeMensagemAsync(CancellationToken cancellationToken, Action<string> tratarObjetoImportado, int prefetchCount)
{
try
{
var receiver = new Microsoft.Azure.ServiceBus.SubscriptionClient(_serviceBusConnString, _topic, _subscription, this._receiveMode, new RetryExponential(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(10), _retryPolicyMaximumRetryCount));
receiver.PrefetchCount = prefetchCount;
receiver.OperationTimeout = TimeSpan.FromMinutes(_timoutOperacao);
var cicloRecebimentoCompleto = new TaskCompletionSource<bool>();
// fecha receiver e factory quando o CancellationToken é acionado
cancellationToken.Register(
async () =>
{
await receiver.CloseAsync();
cicloRecebimentoCompleto.SetResult(true);
});
// registra o RegisterMessageHandler para tratar mensagem lida assincronamente
receiver.RegisterMessageHandler(
async (message, cancellationTokenResponse) =>
{
if (message.Body == null || message.Body.Length == 0)
{
GerenciadorLog.LogInfo($"Mensagem não possui conteudo, mensageId: {message.MessageId}", LogType.Warning);
await receiver.CompleteAsync(message.SystemProperties.LockToken);
}
else
{
try
{
tratarObjetoImportado(Encoding.UTF8.GetString(message.Body));
if (_receiveMode == ReceiveMode.PeekLock)
await receiver.CompleteAsync(message.SystemProperties.LockToken);
}
catch (MessageSizeExceededException ex) {
GerenciadorLog.LogError($"Tamanho da mensagem:{message.MessageId}", ex);
try
{
if (_receiveMode == ReceiveMode.PeekLock)
await receiver.DeadLetterAsync(message.SystemProperties.LockToken);
}
catch (Exception dlex)
{
GerenciadorLog.LogError($"Erro ao enviar mensagem para 'DeadLetter', mensageId: {message.MessageId}", dlex);
throw new Exception("Erro não identificado", dlex);
}
}
catch (MessageLockLostException ex)
{
GerenciadorLog.LogError($"Expirou tempo de leitura da mensagem, será enviada para DeadLetter:{message.MessageId}", ex);
try
{
await receiver.AbandonAsync(message.SystemProperties.LockToken);
}
catch (Exception ex2)
{
GerenciadorLog.LogError($"Erro ao abandonar mensagem, mensageId:{message.MessageId}", ex2);
await Task.CompletedTask;
}
}
catch (MessagingEntityNotFoundException ex)
{
GerenciadorLog.LogError($"Mensagem não encontrada, mensageId:{message.MessageId}", ex);
try
{
await receiver.AbandonAsync(message.SystemProperties.LockToken);
}
catch (Exception ex2)
{
GerenciadorLog.LogError($"Erro ao abandonar mensagem, mensageId:{message.MessageId}", ex2);
await Task.CompletedTask;
}
}
catch (Exception ex)
{
if (ex != null && !string.IsNullOrEmpty(ex.Message))
GerenciadorLog.LogError($"Erro na importação, mensageId:{message.MessageId}", ex);
try
{
if (_receiveMode == ReceiveMode.PeekLock)
await receiver.DeadLetterAsync(message.SystemProperties.LockToken);
}
catch (Exception dlex)
{
GerenciadorLog.LogError($"Erro ao enviar mensagem para 'DeadLetter', mensageId: {message.MessageId}", dlex);
await Task.CompletedTask;
}
}
}
},
new MessageHandlerOptions((e) => LogMessageHandlerException(e, receiver)) { AutoComplete = false, MaxConcurrentCalls = _maxConcurrentCalls, MaxAutoRenewDuration = TimeSpan.FromSeconds(_lockDuration) });
await cicloRecebimentoCompleto.Task;
}
catch (Exception ex)
{
GerenciadorLog.LogError("Erro ao configurar 'listener' para leitura das mensagens.");
GerenciadorLog.LogError(ex.Message, ex);
throw ex;
}
}
And this method keep await the task. Can have more than one thread calling this method
public async Task Run(int segundosIntnervaloSondaConsultaTopico, int prefetchCount, Action<string> tratarObjetoImportado)
{
IList<CancellationTokenSource> cancellationTokensSource = new List<CancellationTokenSource>();
IList<Task> instanciasDasSondas = new List<Task>();
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
GerenciadorLog.LogInfo($"start blablalbala --");
var recebeMensagemAsync = RecebeMensagemAsync(cancellationTokenSource.Token, tratarObjetoImportado, prefetchCount);
await Task.WhenAll(Task.Run(() => Console.ReadKey()),
Task.Delay(TimeSpan.FromSeconds(segundosIntnervaloSondaConsultaTopico)).ContinueWith((t) => cancellationTokenSource),
Task.WhenAll(new Task[] { recebeMensagemAsync }));
}
Somebody knows the correct way to keep running or renew the client of register, or another approach?
It was fixed after update to "Microsoft.Azure.ServiceBus 3.1.1" package:
https://www.nuget.org/packages/Microsoft.Azure.ServiceBus/
tks.
Related
I'm trying to create images in Square but it's stuck at 1336, when I have more than 4000 images to upload at the moment.
Here's the code:
public async Task<bool> CreateOrDeleteImagesAsync(string url, string imageId, bool isDelete)
{
var squareClient = await GetSquareClientAsync();
if (isDelete)
{
try
{
await Task.Delay(500);
await squareClient.CatalogApi.DeleteCatalogObjectAsync(imageId);
return true;
}
catch (ApiException exception)
{
exception.Errors.ForEach(async error =>
{
await _globalLogger.ErrorAsync($"Error Category: {error.Category} Code: {error.Code} Detail: {error.Detail}");
_logger.LogError($"Error Category: {error.Category} Code: {error.Code} Detail: {error.Detail}");
});
}
catch (Exception e)
{
await _globalLogger.ErrorAsync($"An error ocurred: {e.Message}");
_logger.LogError($"An error ocurred: {e.Message}");
}
return false;
}
var imageData = new CatalogImage.Builder()
.Name(imageId)
.Build();
var catalogObject = new CatalogObject.Builder("IMAGE", $"#{imageId}")
.ImageData(imageData)
.Build();
var request = new CreateCatalogImageRequest.Builder(idempotencyKey: Guid.NewGuid().ToString(), image: catalogObject)
.Build();
_logger.LogInformation(JsonConvert.SerializeObject(request, Formatting.Indented));
try
{
var imageFile = new FileStreamInfo(new MemoryStream(await _downloadService.GetDownloadBitsImageUrl(new Uri(url))));
await Task.Delay(500);
await squareClient.CatalogApi.CreateCatalogImageAsync(request: request, imageFile: imageFile);
return true;
}
catch (ApiException exception)
{
exception.Errors.ForEach(async error =>
{
await _globalLogger.ErrorAsync($"Error Category: {error.Category} Code: {error.Code} Detail: {error.Detail}");
_logger.LogError($"Error Category: {error.Category} Code: {error.Code} Detail: {error.Detail}");
});
}
catch (Exception e)
{
await _globalLogger.ErrorAsync($"An error ocurred: {e.Message}");
_logger.LogError($"An error ocurred: {e.Message}");
}
return false;
}
In debugging, when the line
await squareClient.CatalogApi.CreateCatalogImageAsync(request: request, imageFile: imageFile);
is executed, return successful response and returns true. But then, I check how many images are created in Square and returns the same amount
Honestly, I don't know what to do anymore. If someone can help me, I'll be eternally grateful
I want to do 4 actions and each one can throw an exception. I need to execute them all and log all errors that happened along the way
I can do it in a big and clumsy way :
var exceptions = new List<ExceptionType1>();
try {
result1 = await action1();
} catch (ExceptionType1 ex1) {
exceptions.Add(ex1);
logger.Log(ex1);
}
try {
result2 = await action2();
} catch (ExceptionType1 ex1) {
exceptions.Add(ex1);
logger.Log(ex1);
}
try {
result3 = await action3(result1);
} catch (ExceptionType2 ex2) {
var ex1 = new ExceptionType1(ex2);
exceptions.Add(ex1);
logger.Log(ex1);
}
try {
result4 = await action4(result2);
} catch (ExceptionType2 ex2) {
var ex1 = new ExceptionType1(ex2);
exceptions.Add(ex1);
logger.Log(ex1);
}
if (exceptions.Count > 0) {
return false;
}
Obviously sometimes things like that bloat in size quickly
I would like to do it in more elegant way :
var exceptions = new List<ExceptionType1>();
try {
result1 = await action1();
result2 = await action2();
result3 = await action3(result1);
result4 = await action4(result2);
} catch(Exception ex) {
var ex1 = new ExceptionType1(ex);
exceptions.Add(ex1);
logger.Log(ex1);
???
~~Goto try block and continue executing~~
???
}
if (exceptions.Count > 0) {
return false;
}
I tried to find info how to get back into try block and continue executing but was unsuccessfull. Is it possible. Is there any other way around the problem that I didn't consider?
One way I guess (given your reequipments) is to create a local method
var exceptions = new List<Exception>();
async Task<T> DoAsync<T>(Func<Task<T>> func)
{
try
{
return await func();
}
catch (Exception ex)
{
exceptions.Add(ex);
logger.Log(ex);
}
return default;
}
result1 = await DoAsync(action1);
result2 = await DoAsync(action2);
if (exceptions.Count > 0)
{
return false;
}
Maybe you can extract this into a local function:
// declare this inside the method that contains the code you showed
async void GetResult<TResult, TException>(out TResult result, Func<Task<TResul>> resultGetter, Func<TException, ExceptionType1> mapper)
where TException: Exception {
try {
result = await resultGetter();
} catch (TException ex) {
var ex1 = mapper(ex)
exceptions.Add(ex1);
logger.Log(ex1);
}
}
Callers:
GetResult(out result1, action1, (ExceptionType1 e) => e);
GetResult(out result2, action2, (ExceptionType1 e) => e);
GetResult(out result3, async () => await action3(result1), (ExceptionType2 e) => new ExceptionType1(e));
GetResult(out result4, async () => await action4(result2), (ExceptionType2 e) => new ExceptionType1(e));
how to get back into try block and continue executing.. Is it possible?
You can't do what you are looking for: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/try-catch
The block is executed until an exception is thrown or it is completed successfully.
Once out of the block, even the variables that have been initialized are rolled back.
It's the whole point of the exception to stop the execution of the safe guarded code.
Follow the recommendations of the other two answers to simplify your code
I think WhenAll() method for Task will suit your purpose:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/try-catch#taskwhenall-example
First of all, your actions are already async. Moreover, you can divide to several WhenAll() blocks if you need to follow any order of execution
Example from docs:
public async Task action1()
{
throw new InvalidOperationException();
}
public async Task action2()
{
throw new NotImplementedException();
}
public async Task action3()
{
throw new InvalidCastException();
}
public async Task DoMultipleAsync()
{
Task theTask1 = action1();
Task theTask2 = action2();
Task theTask3 = action3();
Task allTasks = Task.WhenAll(theTask1, theTask2, theTask3);
try
{
await allTasks;
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
Console.WriteLine("Task IsFaulted: " + allTasks.IsFaulted);
foreach (var inEx in allTasks.Exception.InnerExceptions)
{
Console.WriteLine("Task Inner Exception: " + inEx.Message);
}
}
}
// Output:
// Exception: Operation is not valid due to the current state of the object.
// Task IsFaulted: True
// Task Inner Exception: Operation is not valid due to the current state of the object.
// Task Inner Exception: The method or operation is not implemented.
// Task Inner Exception: Specified cast is not valid.
I am writing an asp.net web API using Visual Studio 2019. When I write as in the example below, Visual Studio recommends me making the method static. So I followed the suggestions and made all methods of the Web API static. Is this correct? What is the advantage if it is correct and what is the disadvantage if it is wrong?
Thank you...
Severity Code Description Project File Line Suppression State
Message CA1822 Member AdresleriGetir does not access instance data and can be marked as static (Shared in VisualBasic) Devriye.WebApi**
My method:
[HttpPost]
public static Adres[] AdresleriGetir([FromBody]GirisParametresi girisParametresi)
{
if (girisParametresi != null)
{
string query = #"SELECT * FROM ADRESLER WHERE AKTIF=1";
Cagri cagri = new Cagri()
{
Proje = "Devriye.WebApi",
Modul = "AdresController",
Metot = "AdresGetir",
Nesne = new JavaScriptSerializer().Serialize(girisParametresi)
};
Log log = new Log(null, cagri, girisParametresi.Oturum);
using (DataTable dataTable = DataAccessLayer.VerileriGetir(query, null, log))
{
List<Adres> adresler = new List<Adres>();
if (dataTable.Rows.Count > 0)
{
for (int i = 0; i < dataTable.Rows.Count; i++)
{
Adres adres = new Adres();
try { adres.Cadde = Convert.ToString(dataTable.Rows[i]["Cadde".ToUpperInvariant()], WebApiConfig.CultureInfo); } catch (Exception ex) { if (log != null) { log.Hata = new Hata() { Aciklama = ex.Message, HataKodu = 997 }; Task.Run(() => DataAccessLayer.LogKaydet(log)); } }
try { adres.EklenmeTarihi = Convert.ToDateTime(dataTable.Rows[i]["EklenmeTarihi".ToUpperInvariant()], WebApiConfig.CultureInfo); } catch (Exception ex) { if (log != null) { log.Hata = new Hata() { Aciklama = ex.Message, HataKodu = 997 }; Task.Run(() => DataAccessLayer.LogKaydet(log)); } }
try { adres.ID = Convert.ToInt32(dataTable.Rows[i]["ID".ToUpperInvariant()], WebApiConfig.CultureInfo); } catch (Exception ex) { if (log != null) { log.Hata = new Hata() { Aciklama = ex.Message, HataKodu = 997 }; Task.Run(() => DataAccessLayer.LogKaydet(log)); } }
try { adres.Il = Convert.ToString(dataTable.Rows[i]["Il".ToUpperInvariant()], WebApiConfig.CultureInfo); } catch (Exception ex) { if (log != null) { log.Hata = new Hata() { Aciklama = ex.Message, HataKodu = 997 }; Task.Run(() => DataAccessLayer.LogKaydet(log)); } }
try { adres.Ilce = Convert.ToString(dataTable.Rows[i]["Ilce".ToUpperInvariant()], WebApiConfig.CultureInfo); } catch (Exception ex) { if (log != null) { log.Hata = new Hata() { Aciklama = ex.Message, HataKodu = 997 }; Task.Run(() => DataAccessLayer.LogKaydet(log)); } }
try { adres.KapiNo = Convert.ToString(dataTable.Rows[i]["KapiNo".ToUpperInvariant()], WebApiConfig.CultureInfo); } catch (Exception ex) { if (log != null) { log.Hata = new Hata() { Aciklama = ex.Message, HataKodu = 997 }; Task.Run(() => DataAccessLayer.LogKaydet(log)); } }
try { adres.Mahalle = Convert.ToString(dataTable.Rows[i]["Mahalle".ToUpperInvariant()], WebApiConfig.CultureInfo); } catch (Exception ex) { if (log != null) { log.Hata = new Hata() { Aciklama = ex.Message, HataKodu = 997 }; Task.Run(() => DataAccessLayer.LogKaydet(log)); } }
try { adres.PostaKodu = Convert.ToInt32(dataTable.Rows[i]["PostaKodu".ToUpperInvariant()], WebApiConfig.CultureInfo); } catch (Exception ex) { if (log != null) { log.Hata = new Hata() { Aciklama = ex.Message, HataKodu = 997 }; Task.Run(() => DataAccessLayer.LogKaydet(log)); } }
try { adres.Sokak = Convert.ToString(dataTable.Rows[i]["Sokak".ToUpperInvariant()], WebApiConfig.CultureInfo); } catch (Exception ex) { if (log != null) { log.Hata = new Hata() { Aciklama = ex.Message, HataKodu = 997 }; Task.Run(() => DataAccessLayer.LogKaydet(log)); } }
adresler.Add(adres);
}
return adresler.ToArray();
}
else
{
return null;
}
}
}
else
{
return null;
}
}
This function doesn't access any instance data or call any instance methods.
I've had similar questions about R# wanting to convert this type of function to static. See this SO question for some reasons. From the accepted answer in the link;
It makes me ask myself if the method in question should actually be
part of the type or not. Since it doesn't use any instance data, you
should at least consider if it could be moved to its own type. Is it
an integral part of the type, or is it really a general purpose
utility method?
If it does make sense to keep the method on the specific type, there's
a potential performance gain as the compiler will emit different code
for a static method.
I am using httpclient to get data from an Api Rest through Xamarin. My problem happens when I'm going to run httpclient again on a new page to get back the api information, that is, this works only once, how do I solve it?
Code:
private async void ObterNoticiasXbox()
{
var respXbox = string.Empty;
try
{
var uriXbox = new HttpClient()
{
BaseAddress = new Uri("http://api.newsplay.com.br")
};
var urlXbox = "/post/";
var resultXbox = await uriXbox.GetAsync(urlXbox);
if (!resultXbox.IsSuccessStatusCode)
{
await DisplayAlert("Erro de Conexão", "Não foi possível obter as notícias do servidor, Tente novamente mais tarde!", "OK");
return;
}
respXbox = await resultXbox.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
await DisplayAlert("Erro de Conexão com o Servidor", ex.Message, "OK");
return;
}
// transformando o retorno em objeto através do json e deserealize e retornando em lista
var NXbox = JsonConvert.DeserializeObject<List<XboxModels>>(respXbox);
//Adicionando os itens ao ListView na Home.xaml
XboxList.ItemsSource = NXbox;
}
}
I am trying to build a UCMA standalone outbound dialer. Unfortunately I can't find much information on how to connect to a SIP or how to configure this to begin with. I got a GetOnSIP and would like to associate it with my application. Any help would be appreciated!
Thanks
//set up my application
internal void Start()
{
_applicationId = ConfigurationManager.AppSettings["applicationId"];
_recipientSipUri = ConfigurationManager.AppSettings["recipientSipUri"];
//string urisToDialString = ConfigurationManager.AppSettings["numbersToDial"];
_urisToDial.Add("phone number goes here");
ServerPlatformSettings platformSettingsObj = new ServerPlatformSettings(_applicationId, Dns.GetHostEntry("localhost").HostName,
5060, string.Empty /* empty string for the GRUU */);
Utils.WriteDebug("Endpoint: " + platformSettingsObj.Localhost);
_platform = new CollaborationPlatform(platformSettingsObj);
_platform.AllowedAuthenticationProtocol = SipAuthenticationProtocols.None;
try
{
_platform.BeginStartup(ar =>
{
try
{
_platform.EndStartup(ar);
Console.WriteLine("Platform started.");
StartEndpoint();
Console.WriteLine("Platform Endpoint Initiated.");
CallSession sessionObj = new CallSession(_urisToDial.First(), _endpoint);
sessionObj.InitiateCall();
}
catch (RealTimeException ex)
{
Console.WriteLine(ex);
}
}, null);
}
catch (InvalidOperationException ex)
{
Console.WriteLine(ex);
}
}
private void StartEndpoint()
{
// Create a placeholder URI for the endpoint.
ApplicationEndpointSettings endpointSettings =
new ApplicationEndpointSettings("sip:default#" +
Dns.GetHostEntry("localhost").HostName);
// Make this a default routing endpoint, so that
// all requests sent to the listening port on this IP,
// regardless of To URI, will come to the endpoint.
endpointSettings.IsDefaultRoutingEndpoint = true;
// Create a new endpoint and register for AV calls.
_endpoint = new ApplicationEndpoint(_platform, endpointSettings);
_endpoint.RegisterForIncomingCall<AudioVideoCall>(OnCallReceived);
try
{
_endpoint.BeginEstablish(ar =>
{
try
{
_endpoint.EndEstablish(ar);
Console.WriteLine("Endpoint started.");
}
catch (RealTimeException ex)
{
Console.WriteLine(ex);
}
}, null);
}
catch (InvalidOperationException ex)
{
Console.WriteLine(ex);
}
}
public CallSession(string number, ApplicationEndpoint endpointObj)
{
// Set the host and port to which the INVITE should be sent
// i'm going to guess that this is where the sbc ip goes
ConnectionContext connectionContextObj = new ConnectionContext("192.168.0.56", 5060);
optionsObj.ConnectionContext = connectionContextObj;
//configure this to use udp
_phoneNumber = number;
_endpoint = endpointObj;
}
public bool InitiateCall()
{
bool isInitiated = true;
try
{
Utils.WriteDebug("About to Initiate a phone Call");
Conversation convObj = new Conversation(_endpoint);
AudioVideoCall avcallObj = new AudioVideoCall(convObj);
// Establish the call using the options we created
//avcall.BeginEstablish("sip:test#test.greenl.ee", optionsObj,
avcallObj.BeginEstablish("tel:+" + _phoneNumber, optionsObj,
ar =>
{
try
{
avcallObj.EndEstablish(ar);
Console.WriteLine("The call with Local Participant: " + avcallObj.Conversation.LocalParticipant + " and Remote Participant: " + avcallObj.RemoteEndpoint.Participant + " is now in the established state.");
}
catch (RealTimeException ex)
{
isInitiated = false;
Utils.LogError(ex);
}
},
null);
}
catch (InvalidOperationException ex)
{
isInitiated = false;
Utils.LogError(ex);
}
return isInitiated;
}