WPF, C# TPL AggregateException never fired - c#

I am trying to develop a small application with WPF, C#. I encountered a problem when trying to use the library TPL, especially exception handling. The problem is that AggregateException is never captured, and the program displays an exception in the method I passed as a task. here's my code. I removed unnecessary code :
private void RefreshOldDossierFinancementCommandExecute(KeyEventArgs e)
{
bool processIt = false;
if (e != null && e.Key == Key.Enter)
processIt = true;
if (e == null || processIt == true)
{
TaskInProgress = true;
SBMessage = "Query In progress...";
var uischeduler = TaskScheduler.FromCurrentSynchronizationContext();
var refreshold = Task.Factory.StartNew(() =>
RefreshOldDossierFinancement(DossierFinancementEnteredKey));
refreshold.ContinueWith(task => { TaskInProgress = false; },
CancellationToken.None,
TaskContinuationOptions.NotOnFaulted, uischeduler);
try
{
refreshold.Wait();
}
catch (AggregateException aex) //This Exception is never fired
{
Messenger.Default.Send(new ExceptionMessageRefresh(aex), "DossierFinancement");
}
}
}
private void RefreshOldDossierFinancement(long dfId)
{
TotalContrats = 0.000M;
TotalMefs = 0.000M;
TotalCommandes = 0.000M;
decimal phb = 0.000M;
decimal pctr = 0.000M;
decimal pmef = 0.000M;
PercentageHorsBilan = "(0%)";
PercentageContrats = "(0%)";
PercentageMef = "(0%)";
DossierNumber = "";
using (UnitOfWork cx = new UnitOfWork(_currentLog))
{
// try
{
IDossierFinancementRepository sr = new DossierFinancementRepository(cx, _currentLog);
IDossierFinancementManagementService dfms = new DossierFinancementManagementService(_currentLog, sr);
IDataTraceRepository dtr = new DataTraceRepository(cx, _currentLog);
IDataTraceManagementService dtms = new DataTraceManagementService(_currentLog, dtr);
CurrentDossierFinancement = dfms.FindById(dfId);
//I put this code in comment to force a nullReferenceException exception
/*if (CurrentDossierFinancement == null) //Not Found
Messenger.Default.Send<NotificationMessage>(new NotificationMessage("Dossier Financement n° " + dfId.ToString() + " introuvable."),"DossierFinancementError");
else*/
{
//The debugger stops here with NullRefrenceException Exception
// I want this exception to be captured in AggregateException
DossierFinancementEnteredKey = CurrentDossierFinancement.DossierId;
DossierNumber = "N° " + DossierFinancementEnteredKey.ToString();
RequestNature = (CurrentDossierFinancement.InvestmentGoal == 0) ? "Création" : (CurrentDossierFinancement.InvestmentGoal == 1) ? "Renouvellement" : "Extension";
EtatDossier = (CurrentDossierFinancement.Status == 1) ? "En cours" : (CurrentDossierFinancement.Status == 2) ? "Approuvé" : "Rejeté";
if (CurrentDossierFinancement.ClientId != null)
{
CustomerCode = (long)CurrentDossierFinancement.ClientId;
CustomerName = CurrentDossierFinancement.Client.NomCli;
}
else
{
CustomerCode = 0;
if (CurrentDossierFinancement.ClientType == 1)
CustomerName = CurrentDossierFinancement.Name + " " + CurrentDossierFinancement.FirstName;
else
CustomerName = CurrentDossierFinancement.CompanyName;
}
if (CurrentDossierFinancement.Contrat != null)
{
TotalContrats = CurrentDossierFinancement.Contrat.Montant;
TotalHorsBilan = CurrentDossierFinancement.Contrat.Montant;
pctr = Math.Round((TotalContrats / CurrentDossierFinancement.Montant) * 100, 0);
PercentageContrats = "(" + pctr.ToString() + "%)";
if (CurrentDossierFinancement.Contrat.Mefs != null)
{
TotalMefs = CurrentDossierFinancement.Contrat.Mefs.Sum(x => x.Montant);
pmef = Math.Round((TotalMefs / CurrentDossierFinancement.Montant) * 100, 0);
PercentageMef = "(" + pmef.ToString() + "%)";
}
TotalHorsBilan = TotalContrats - TotalMefs;
phb = Math.Round((TotalHorsBilan / CurrentDossierFinancement.Montant) * 100, 0);
PercentageHorsBilan = "(" + phb.ToString() + "%)";
}
//Extraire la trace
List<DataTrace> traceList = dtms.GetTrace(DossierFinancementEnteredKey, "DossierFinancement").ToList();
DataTrace newRecord = traceList.Where(xx => string.Equals(xx.ActionLib, "New", StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
if (newRecord != null)
{
CreatedBy = newRecord.Coduser;
CreatedAt = newRecord.ActionDate.ToString();
}
}
}
/*
catch (Exception ex)
{
throw ex;
}*/
}
}
I tested the following code and it still doesn't work :
Task.Run(() =>
{
RefreshOldDossierFinancement(DossierFinancementEnteredKey);
}
catch (AggregateException aex)
{
Messenger.Default.Send(new ExceptionMessageRefresh(aex), "DossierFinancement");
}}).ContinueWith(task => { TaskInProgress = false; },
CancellationToken.None,
TaskContinuationOptions.NotOnFaulted, uischeduler
);

A simpler approach to using continuations is to use async-await. When we execute a delegate using Task.Run, and want to asynchronously wait for it's completion, we can await it:
private async void RefreshOldDossierFinancementCommandExecute(KeyEventArgs e)
{
bool processIt = false;
if (e != null && e.Key == Key.Enter)
processIt = true;
if (!processIt)
return;
TaskInProgress = true;
SBMessage = "Query In progress...";
try
{
await Task.Run(() => RefreshOldDossierFinancement(DossierFinancementEnteredKey));
}
catch (Exception e)
{
// Do stuff
}
finally
{
TaskInProgress = false;
}
}
This way, you don't need to explicitly capture the SynchronizationContext, and you don't block the UI thread while the operation is on-going.

Finally i found a solution, I dont know if it is the best.
I modified my code as follows :
private void RefreshOldDossierFinancementCommandExecute(KeyEventArgs e)
{
bool processIt = false;
if (e != null && e.Key == Key.Enter)
processIt = true;
if (e == null || processIt == true)
{
TaskInProgress = true;
SBMessage = "Query in progress...";
var uischeduler = TaskScheduler.FromCurrentSynchronizationContext();
Task.Run(() =>
{
RefreshOldDossierFinancement(DossierFinancementEnteredKey);
}).ContinueWith(task => { TaskInProgress = false; },
CancellationToken.None,
TaskContinuationOptions.NotOnFaulted, uischeduler);
}
}
and i capture the exception in RefreshOldDossierFinancement Method. The trick lies to add a Dispatch.BeginInvoke in code behind of the window.
Here The code of RefreshOldDossierFinancement Method :
private void RefreshOldDossierFinancement(long dfId)
{
TotalContrats = 0.000M;
TotalMefs = 0.000M;
TotalCommandes = 0.000M;
decimal phb = 0.000M;
decimal pctr = 0.000M;
decimal pmef = 0.000M;
PercentageHorsBilan = "(0%)";
PercentageContrats = "(0%)";
PercentageMef = "(0%)";
DossierNumber = "";
using (UnitOfWork cx = new UnitOfWork(_currentLog))
{
try
{
IDossierFinancementRepository sr = new DossierFinancementRepository(cx, _currentLog);
IDossierFinancementManagementService dfms = new DossierFinancementManagementService(_currentLog, sr);
IDataTraceRepository dtr = new DataTraceRepository(cx, _currentLog);
IDataTraceManagementService dtms = new DataTraceManagementService(_currentLog, dtr);
CurrentDossierFinancement = dfms.FindById(dfId);
/*if (CurrentDossierFinancement == null) //Not Found
Messenger.Default.Send<NotificationMessage>(new NotificationMessage("Dossier Financement n° " + dfId.ToString() + " introuvable."),"DossierFinancementError");
else*/
{
DossierFinancementEnteredKey = CurrentDossierFinancement.DossierId;
DossierNumber = "N° " + DossierFinancementEnteredKey.ToString();
RequestNature = (CurrentDossierFinancement.InvestmentGoal == 0) ? "Création" : (CurrentDossierFinancement.InvestmentGoal == 1) ? "Renouvellement" : "Extension";
EtatDossier = (CurrentDossierFinancement.Status == 1) ? "En cours" : (CurrentDossierFinancement.Status == 2) ? "Approuvé" : "Rejeté";
if (CurrentDossierFinancement.ClientId != null)
{
CustomerCode = (long)CurrentDossierFinancement.ClientId;
CustomerName = CurrentDossierFinancement.Client.NomCli;
}
else
{
CustomerCode = 0;
if (CurrentDossierFinancement.ClientType == 1)
CustomerName = CurrentDossierFinancement.Name + " " + CurrentDossierFinancement.FirstName;
else
CustomerName = CurrentDossierFinancement.CompanyName;
}
if (CurrentDossierFinancement.Contrat != null)
{
TotalContrats = CurrentDossierFinancement.Contrat.Montant;
TotalHorsBilan = CurrentDossierFinancement.Contrat.Montant;
pctr = Math.Round((TotalContrats / CurrentDossierFinancement.Montant) * 100, 0);
PercentageContrats = "(" + pctr.ToString() + "%)";
if (CurrentDossierFinancement.Contrat.Mefs != null)
{
TotalMefs = CurrentDossierFinancement.Contrat.Mefs.Sum(x => x.Montant);
pmef = Math.Round((TotalMefs / CurrentDossierFinancement.Montant) * 100, 0);
PercentageMef = "(" + pmef.ToString() + "%)";
}
TotalHorsBilan = TotalContrats - TotalMefs;
phb = Math.Round((TotalHorsBilan / CurrentDossierFinancement.Montant) * 100, 0);
PercentageHorsBilan = "(" + phb.ToString() + "%)";
}
//Extraire la trace
List<DataTrace> traceList = dtms.GetTrace(DossierFinancementEnteredKey, "DossierFinancement").ToList();
DataTrace newRecord = traceList.Where(xx => string.Equals(xx.ActionLib, "New", StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
if (newRecord != null)
{
CreatedBy = newRecord.Coduser;
CreatedAt = newRecord.ActionDate.ToString();
}
}
}
catch (Exception ex)
{
//Here i send a message to Window to display The Exception Message in a custom Dialog
Messenger.Default.Send(new ExceptionMessageRefresh(ex), "DossierFinancement");
}
}
}
And finally here The code Behind of The window :
public partial class Dossier : Window
{
public Dossier()
{
InitializeComponent();
Messenger.Default.Register<ExitMessage>(this, "DossierFinancement", (action) => CloseWindow(action));
Messenger.Default.Register<ExceptionMessageRefresh>(this, "DossierFinancement", (action) => ShowExceptionMessage(action));
Messenger.Default.Register<NotificationMessage>(this, "DossierFinancementInfo", (action) => ProcessNotification(action));
Messenger.Default.Register<NotificationMessage>(this, "DossierFinancementError", (action) => ProcessErrorDialogNotification(action));
}
private void ProcessNotification(NotificationMessage action)
{
MessageBox.Show(action.Notification.ToString(), "Information", MessageBoxButton.OK,MessageBoxImage.Information);
}
private void ProcessErrorDialogNotification(NotificationMessage action)
{
MessageBox.Show(action.Notification.ToString(), "Erreur", MessageBoxButton.OK, MessageBoxImage.Error);
}
private void CloseWindow(ExitMessage action)
{
this.Close();
Messenger.Default.Unregister<ExitMessage>(this, "DossierFinancement");
}
private void ShowExceptionMessage(ExceptionMessageRefresh obj)
{
//Without the following Call of Dispatcher, An exception "Thread must be STA... will be fired
Dispatcher.BeginInvoke(new Action(() =>
{
UICommon.ShowErrorMessage(obj.ExceptionToRefresh);
}));
}
}
and that's all.
Thanks.

Related

How to fill entry with missing when nothing was writte in in xamarin app?

I am doing Import page and if user leave some entry blank and click on import button I want to fill blank entries with Missing. I have tried that like this:
if (liveryEntry.Text == null)
{
liveryEntry.Text = "Missing";
}
if (registrationEntry.Text == null)
{
registrationEntry.Text = "Missing";
}
if (airportEntry == null)
{
airportEntry.Text = "Missing";
}
if (commentEntry == null)
{
commentEntry.Text = "Missing";
}
But sometimes it works and fill it with Missing, sometimes it doesnt work. What is wrong or is there another way to do that?
Here is full code of method:
private async void buttonImport_Clicked(object sender, EventArgs e)
{
var db = new SQLiteConnection(_dbPath);
db.CreateTable<Airplane>();
collectionPlane.IsVisible = false;
collectionAirline.IsVisible = false;
collectionLivery.IsVisible = false;
collectionRegistration.IsVisible = false;
collectionAirport.IsVisible = false;
try
{
if (liveryEntry.Text == null)
{
liveryEntry.Text = "Missing";
}
if (registrationEntry.Text == null)
{
registrationEntry.Text = "Missing";
}
if (airportEntry == null)
{
airportEntry.Text = "Missing";
}
if (commentEntry == null)
{
commentEntry.Text = "Missing";
}
if (planeEntry.Text != null && airlineEntry.Text != null)
{
var url = PhotoPick();
int i = 1;
int same = 0;
string fileName = registrationEntry.Text;
for (int b = 1; b <= GetNumberPhotos(); b++)
{
if (db.Table<Airplane>().FirstOrDefault(d => d.Id == b) != null)
{
var rowData = db.Table<Airplane>().FirstOrDefault(d => d.Id == b);
string match = rowData.Registration;
if (fileName == match)
{
same++;
}
}
}
i = 1 + same;
fileName = registrationEntry.Text + "-" + i;
var thumbUrl = CreateThumbnail(await url, fileName);
var maxPK = db.Table<Airplane>().OrderByDescending(c => c.Id).FirstOrDefault();
Airplane airplane = new Airplane()
{
Id = (maxPK == null ? 1 : maxPK.Id + 1),
SearchId = planeEntry.Text + airlineEntry.Text + liveryEntry.Text + registrationEntry.Text + airportEntry.Text + datePicker.Date.ToString() + commentEntry.Text,
Plane = planeEntry.Text.ToUpper(),
Airline = airlineEntry.Text,
Livery = liveryEntry.Text,
Registration = registrationEntry.Text.ToUpper(),
Airport = airportEntry.Text.ToUpper(),
Date = datePicker.Date,
Comment = commentEntry.Text,
Url = await url,
ThumbnailUrl = thumbUrl
};
db.Insert(airplane);
await DisplayAlert("Saved", planeEntry.Text + " of " + airlineEntry.Text + " is saved.", "OK");
planeEntry.Text = "";
airlineEntry.Text = "";
liveryEntry.Text = "";
registrationEntry.Text = "";
airportEntry.Text = "";
commentEntry.Text = "";
}
else
await DisplayAlert("Fill all needed fields", "You have to fill all fields except livery and comment", "OK");
}
catch
{
await DisplayAlert("Error", "Something went wrong", "Try again");
}
}
It is probably some kind of bug or missunderstanding #Cfun have solved with if ( string.IsNullOrEmpty(liveryEntry.Text)) and it works as expected.

asynchronous datagrid view c#

People would like to ask you for help with the following situation.
I have a monitor where I check if certain machines are online. To make this process I have a script running on the machine feeding the database with the current time. Already on the monitor, I have an asynchronous check in Infinite loop to pick up the last updated time of the bank and update my Data Grid View. However I'm having some locking problems in this loop, someone could help follow my code
private void timer1_Tick(object sender, EventArgs e)
{
if (timerExec)
{
timerExec = false;
selectStatusRobos();
}
//timer1.Enabled = false;
}
public async void selectStatusRobos()
{
String Configuracao = "server=;user=midas_Client;password=;database=;port=3306";
string query = "SELECT i.Usuario_meta, i.Nome_robo, i.Simbolo, i.Periodo, i.Status_op, i.Operacao, i.Hora_criacao, c.Id, i.Corretora FROM int00 AS i INNER JOIN cliente00 AS c ON i.Usuario_meta = c.Usuario_meta AND i.Corretora = c.Corretora";
MySqlConnection conexao = new MySqlConnection(Configuracao);
try
{
await conexao.OpenAsync();
MySqlCommand COMANDO = new MySqlCommand(query, conexao);
MySqlDataAdapter adapter = new MySqlDataAdapter(COMANDO);
DataTable status = new DataTable();
await adapter.FillAsync(status);
bool flag_find = false;
for (int i = 0; i < dataGridView1.RowCount; i++)
{
flag_find = false;
dataGridView1.Rows[i].Cells["Status"].Value = Properties.Resources.if_exclamation_red_46014;
dataGridView1.Rows[i].Cells["Operacao"].Value = Properties.Resources.if_op_null;
dataGridView1.Rows[i].Cells["Status_op_img"].Value = Properties.Resources.if_op_null;
for (int b = 0; b < status.Rows.Count; b++)
{
if (dataGridView1.Rows[i].Cells["Id"].Value.ToString() == status.Rows[b]["Id"].ToString()
&& dataGridView1.Rows[i].Cells["Usuario_meta"].Value.ToString() == status.Rows[b]["Usuario_meta"].ToString()
&& dataGridView1.Rows[i].Cells["Corretora"].Value.ToString() == status.Rows[b]["Corretora"].ToString()
&& dataGridView1.Rows[i].Cells["Nome_robo"].Value.ToString() == status.Rows[b]["Nome_robo"].ToString()
&& dataGridView1.Rows[i].Cells["Simbolo"].Value.ToString() == status.Rows[b]["Simbolo"].ToString().Substring(0, 3)
&& dataGridView1.Rows[i].Cells["Periodo"].Value.ToString() == status.Rows[b]["Periodo"].ToString())
{
flag_find = true;
dataGridView1.Rows[i].Cells["Status"].Value = Properties.Resources.if_tick_circle_frame_27247;
dataGridView1.Rows[i].Cells["Hora_ultima"].Value = status.Rows[b]["Hora_criacao"].ToString();
if (status.Rows[b]["Operacao"].ToString() == "1") // Compra
{
dataGridView1.Rows[i].Cells["Operacao_img"].Value = Properties.Resources.if_Raise_32535_16;
dataGridView1.Rows[i].Cells["Operacao"].Value = status.Rows[b]["Operacao"].ToString();
}
else if (status.Rows[b]["Operacao"].ToString() == "2") // Venda
{
dataGridView1.Rows[i].Cells["Operacao_img"].Value = Properties.Resources.if_Fall_32468_16;
dataGridView1.Rows[i].Cells["Operacao"].Value = status.Rows[b]["Operacao"].ToString();
}
else
{
dataGridView1.Rows[i].Cells["Operacao_img"].Value = Properties.Resources.if_op_null;
dataGridView1.Rows[i].Cells["Operacao"].Value = status.Rows[b]["Operacao"].ToString();
}
if (status.Rows[b]["Status_op"].ToString() == "2") // Off
{
dataGridView1.Rows[i].Cells["Status_op_img"].Value = Properties.Resources.if_power_off_10214;
dataGridView1.Rows[i].Cells["Status_op"].Value = status.Rows[b]["Status_op"].ToString();
}
else if (status.Rows[b]["Status_op"].ToString() == "1") // On
{
dataGridView1.Rows[i].Cells["Status_op_img"].Value = Properties.Resources.if_power_on_10215;
dataGridView1.Rows[i].Cells["Status_op"].Value = status.Rows[b]["Status_op"].ToString();
}
dataGridView1.Rows[i].Cells["Status"].Value = Properties.Resources.if_tick_circle_frame_27247;
//query = "DELETE FROM `int00` WHERE Usuario_meta = #usuario_meta AND Nome_robo = #nome_robo AND Simbolo = #simbolo AND Periodo = #periodo";
//COMANDO.CommandText = query;
//COMANDO.Parameters.Clear();
//COMANDO.Parameters.Add("#usuario_meta", MySqlDbType.VarChar).Value = status.Rows[b]["Usuario_meta"].ToString();
//COMANDO.Parameters.Add("#nome_robo", MySqlDbType.VarChar).Value = status.Rows[b]["Nome_robo"].ToString();
//COMANDO.Parameters.Add("#simbolo", MySqlDbType.VarChar).Value = status.Rows[b]["Simbolo"].ToString();
//COMANDO.Parameters.Add("#periodo", MySqlDbType.VarChar).Value = status.Rows[b]["Periodo"].ToString();
//COMANDO.ExecuteNonQuery();
//break;
}
if (dataGridView1.Rows[i].Cells["Hora_ultima"].Value != null)
{
DateTime t = Convert.ToDateTime(dataGridView1.Rows[i].Cells["Hora_ultima"].Value.ToString());
// if (dataGridView1.Rows[i].Cells["Hora_ultima"].Value.ToString() != status.Rows[b]["Hora_criacao"].ToString())
if (flag_find)
{
DateTime t1 = DateTime.Now;
DateTime t2 = DateTime.Now.AddSeconds(-30);
System.TimeSpan diff2 = t1.Subtract(t);
if (diff2.TotalSeconds >= 15 && diff2.TotalSeconds <= 45)
{
dataGridView1.Rows[i].Cells["Status"].Value = Properties.Resources.if_58_62715;
}
else if (diff2.TotalSeconds < 15 && diff2.TotalSeconds >= 0)
{
dataGridView1.Rows[i].Cells["Status"].Value = Properties.Resources.if_tick_circle_frame_27247;
}
else
{
dataGridView1.Rows[i].Cells["Status"].Value = Properties.Resources.if_exclamation_red_46014;
}
}
}
}
}
//frm = this.MdiParent as frmPrincipal;
//SendMessage send = new SendMessage(frm.SetLabel);
//send(DateTime.Now.ToString("HH:mm :ss") + " - Dados Atualizados...", null, null);
conexao.Close();
}
catch (MySqlException ex)
{
frm = this.MdiParent as frmPrincipal;
SendMessage send = new SendMessage(frm.SetLabel);
send(DateTime.Now.ToString("HH:mm :ss") + " - Tempo limite excedido na seleção", ex.Message + ex.StackTrace, Properties.Resources.if_Close_Icon_Dark_1398917, 15000);
//MessageBox.Show(ex.Message + ex.StackTrace, "Detalhes Exception");
timerExec = true;
}
catch (TimeoutException ex)
{
frm = this.MdiParent as frmPrincipal;
SendMessage send = new SendMessage(frm.SetLabel);
send(DateTime.Now.ToString("HH:mm :ss") + " - Tempo limite excedido na seleção", ex.Message + ex.StackTrace, Properties.Resources.if_Close_Icon_Dark_1398917, 15000);
timerExec = true;
}
finally
{
frm = this.MdiParent as frmPrincipal;
SendMessage send = new SendMessage(frm.SetLabel);
send(DateTime.Now.ToString("HH:mm :ss") + " - Dados Atualizados...", null, null, 15000);
conexao.Close();
timerExec = true;
}
}

Message body empty on quickblox ios in xamarin native c#

i've translated the quickblox's sample app for Xamarin forms in Xamarin iOS and Android native.
Everything works "except" that the retrieving of the message fails.
I send the message from one client, and the event is catched from the other chat occupant:
XMPP: DispatchEvents ====> <message id="580735ed335fb760ae0017ec" xmlns="jabber:client" from="18029700-46533#chat.quickblox.com/1220770403-quickblox-68179" type="chat" to="18976912-46533#chat.quickblox.com"><extraParams xmlns="jabber:client"><save_to_history>1</save_to_history><dialog_id>5800aea1a28f9a1c1f000010</dialog_id><message_id>580735ed335fb760ae0017ec</message_id><date_sent>1476867565</date_sent></extraParams><body>test+message</body><thread>5800aea1a28f9a1c1f000010</thread></message>
XMPP: OnMessageReceived ====> From: 18029700 To: 18976912 Body: DateSent 1476867565 FullXmlMessage: <message id="580735ed335fb760ae0017ec" xmlns="jabber:client" from="18029700-46533#chat.quickblox.com/1220770403-quickblox-68179" type="chat" to="18976912-46533#chat.quickblox.com"><extraParams xmlns="jabber:client"><save_to_history>1</save_to_history><dialog_id>5800aea1a28f9a1c1f000010</dialog_id><message_id>580735ed335fb760ae0017ec</message_id><date_sent>1476867565</date_sent></extraParams><body>test+message</body><thread>5800aea1a28f9a1c1f000010</thread></message>
as you can see the Body part into the event OnMessageReceived is empty!
But the html part in the end of this snippet contains the message "test+message"
this is the PrivateChat Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using QbChat.Pcl.Repository;
using Quickblox.Sdk.GeneralDataModel.Models;
using Quickblox.Sdk.Modules.ChatXmppModule;
using Quickblox.Sdk.Modules.UsersModule.Models;
using UIKit;
using Xmpp.Im;
namespace KeepInTouch.iOS
{
public partial class PrivateChat : BaseChat
{
PrivateChatManager privateChatManager;
public PrivateChat(string dialogId, string nibname) : base(dialogId, nibname) { }
public async override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
AppDelegate.R.NavController.SetNavigationBarHidden(true, true);
await MessageProvider.Reconnect();
}
public override void ViewDidLoad()
{
base_tb_chat = tb_chat;
base_txt_chat = txt_chat;
base.ViewDidLoad();
view_top.BackgroundColor = UIColor.FromPatternImage(UIImage.FromFile("navbar_top_kit.png"));
tb_chat.TableFooterView = new UIView();
IsBusyIndicatorVisible = true;
var dialog = Database.Instance().GetDialog(dialogId);
var opponentId = dialog.OccupantIds.Split(',').Select(int.Parse).First(id => id != QbChat.UserId);
ChatXmppClient xmpc = QbChat.QbProvider.GetXmppClient();
privateChatManager = xmpc.GetPrivateChatManager(opponentId, dialogId);
privateChatManager.MessageReceived += OnMessageReceived;
DialogName = dialog.Name;
//xmpc.MessageReceived += OnMessageReceived;
btn_chat.TouchUpInside += async delegate {
await SendMessageCommandExecute();
txt_chat.Text = "";
};
txt_chat.ShouldReturn += (textField) => {
textField.ResignFirstResponder();
return true;
};
txt_chat.EditingChanged += async delegate {
MessageText = txt_chat.Text;
await MessageProvider.Reconnect();
};
btn_back.TouchUpInside += delegate {
DismissViewController(false, null);
};
IsBusyIndicatorVisible = true;
Task.Factory.StartNew(async () => {
var users = await QbChat.QbProvider.GetUsersByIdsAsync(dialog.OccupantIds);
var opponentUser = users.FirstOrDefault(u => u.Id != QbChat.UserId);
if (opponentUser != null && opponentUser.BlobId.HasValue) {
await QbChat.QbProvider.GetImageAsync(opponentUser.BlobId.Value).ContinueWith((task, result) => {
//var bytes =
task.ConfigureAwait(true).GetAwaiter().GetResult();
}, TaskScheduler.FromCurrentSynchronizationContext());
}
opponentUsers = new List<User> { opponentUser };
await LoadMessages();
InvokeOnMainThread(() =>
IsBusyIndicatorVisible = false
);
});
}
async void OnMessageReceived(object sender, MessageEventArgs messageEventArgs)
{
if (messageEventArgs.MessageType == MessageType.Chat ||
messageEventArgs.MessageType == MessageType.Groupchat) {
string decodedMessage = System.Net.WebUtility.UrlDecode(messageEventArgs.Message.MessageText);
var messageTable = new MessageTable();
messageTable.SenderId = messageEventArgs.Message.SenderId;
messageTable.DialogId = messageEventArgs.Message.ChatDialogId;
messageTable.DateSent = messageEventArgs.Message.DateSent;
if (messageEventArgs.Message.NotificationType != 0) {
if (messageEventArgs.Message.NotificationType == NotificationTypes.GroupUpdate) {
if (messageEventArgs.Message.AddedOccupantsIds.Any()) {
var userIds = new List<int>(messageEventArgs.Message.AddedOccupantsIds);
userIds.Add(messageEventArgs.Message.SenderId);
var users = await QbChat.QbProvider.GetUsersByIdsAsync(string.Join(",", userIds));
var addedUsers = users.Where(u => u.Id != messageEventArgs.Message.SenderId);
var senderUser = users.First(u => u.Id == messageEventArgs.Message.SenderId);
messageTable.Text = senderUser.FullName + " added users: " + string.Join(",", addedUsers.Select(u => u.FullName));
} else if (messageEventArgs.Message.DeletedOccupantsIds.Any()) {
var userIds = new List<int>(messageEventArgs.Message.DeletedOccupantsIds);
var users = await QbChat.QbProvider.GetUsersByIdsAsync(string.Join(",", userIds));
messageTable.Text = string.Join(",", users.Select(u => u.FullName)) + " left this room";
}
//var dialogInfo = await QbChat.QbProvider.GetDialogAsync(messageEventArgs.Message.ChatDialogId);
//if (dialogInfo == null)
//{
// return;
//}
//var dialog = new DialogTable(dialogInfo);
//Database.Instance().SaveDialog(dialog);
}
} else {
messageTable.Text = decodedMessage;
}
await SetRecepientName(messageTable);
Messages.Add(messageTable);
InvokeOnMainThread(async () => {
tb_chat.ReloadData();
await ScrollList();
});
}
}
public async Task LoadMessages()
{
List<Message> messages;
try {
messages = await QbChat.QbProvider.GetMessagesAsync(dialogId);
} catch (Exception ex) {
Console.WriteLine(ex);
return;
}
if (messages != null) {
messages = messages.OrderBy(message => message.DateSent).ToList();
foreach (var message in messages) {
var chatMessage = new MessageTable();
chatMessage.DateSent = message.DateSent;
chatMessage.SenderId = message.SenderId;
chatMessage.MessageId = message.Id;
if (message.RecipientId.HasValue)
chatMessage.RecepientId = message.RecipientId.Value;
chatMessage.DialogId = message.ChatDialogId;
chatMessage.IsRead = message.Read == 1;
await SetRecepientName(chatMessage);
chatMessage.Text = System.Net.WebUtility.UrlDecode(message.MessageText);
InvokeOnMainThread(() =>
Messages.Add(chatMessage)
);
}
InvokeOnMainThread(async () => {
tb_chat.ReloadData();
await ScrollList();
});
}
}
async Task SendMessageCommandExecute()
{
var message = MessageText != null ? MessageText.Trim() : string.Empty;
if (!string.IsNullOrEmpty(message)) {
var m = new MessageTable();
m.SenderId = QbChat.UserId;
m.Text = message;
m.DialogId = dialogId;
m.RecepientFullName = "Me";
try {
await MessageProvider.Reconnect();
var encodedMessage = System.Net.WebUtility.UrlEncode(message);
privateChatManager.SendMessage(encodedMessage);
} catch (Exception ex) {
Console.WriteLine(ex);
return;
}
long unixTimestamp = DateTime.UtcNow.Ticks - new DateTime(1970, 1, 1).Ticks;
unixTimestamp /= TimeSpan.TicksPerSecond;
m.DateSent = unixTimestamp;
m.ID = Database.Instance().SaveMessage(m);
var dialog = Database.Instance().GetDialog(dialogId);
dialog.LastMessage = m.Text;
dialog.LastMessageSent = DateTime.UtcNow;
Database.Instance().SaveDialog(dialog, true);
Messages.Add(m);
MessageText = "";
InvokeOnMainThread(async () => {
tb_chat.ReloadData();
await ScrollList();
});
}
}
public override void DidReceiveMemoryWarning()
{
base.DidReceiveMemoryWarning();
}
}
}
long story short the sdk receive the message but apparently fail to parse the body message. fire the handler but if empty don't call the privateChatManager.MessageReceived.
could anyone help please?
Thank you

OutOfMemory Exception for Parallel.ForEach

I have a console application which runs as 32 bit process(we cant change it to 64 bit) and is throwing Out of memory Exception. We traced minor Memory leak(related to Entity Framework repository) in a downstream process but with that too application should not cross 2 GB memory.
One thing i want to understand is sometimes application processes 2500 records while other times it fails at 100.(Server memory utilization is under 60% when this application is running
I am using Parallel.forEach and controlling number of threads to 4 using ParallelOptions. Can anybody suggest making the application on a single thread may by any chance resolve the problem.
(The application didn't fail in any lower environment but only in production and giving us a very hard time).
Below is the code snippet.
Thanks In Advance,
Rohit
protected override void Execute(IEnumerable<PlanPremiumDetails> argument)
{
if (argument.Any())
{
var EnrollmentRequests = argument.GroupBy(c => c.CaseNumber).ToList();
SelectedPlanPremiumDetails request;
EnrollmentResponse enrollmentResponse;
bool taskStatus;
Common.Status.TotalAutoEnrollRecords = EnrollmentRequests.Count;
Common.StartTimer();
Action<IGrouping<int,PlanPremiumDetails>> processRequest = eRequest =>
{
int caseNumber;
List<EnrolledIndividual> enrolledIndividuals;
try
{
string errorMessage;
caseNumber = eRequest.Key;
if (eRequest.Any(f => f.FailedMCOEnrollmentId > 0))
{
request = FailedMcoRequest(eRequest, caseNumber);
enrollmentResponse = InvokeEnrollment(request);
if (enrollmentResponse.OverallStatus == false && enrollmentResponse.ErrorInformationMA != null)
{
StringBuilder messages = new StringBuilder();
if (enrollmentResponse.ErrorInformationMA.ErrorInformationPostMcaps != null)
{
messages.Append(enrollmentResponse.ErrorInformationMA.ErrorInformationPostMcaps.Message);
Exception innerExp = enrollmentResponse.ErrorInformationMA.ErrorInformationPostMcaps.InnerException;
if (innerExp != null)
{
// messages.Append(enrollmentResponse.ErrorInformationMA.ErrorInformationPostMcaps.InnerException.Message);
do
{
messages.Append(innerExp.Message);
innerExp = innerExp.InnerException;
}
while (innerExp != null);
}
}
else
{
if (enrollmentResponse.ErrorInformationMA != null && enrollmentResponse.ErrorInformationMA.InnerErrorInfo != null)
{
foreach (var msg in enrollmentResponse.ErrorInformationMA.InnerErrorInfo)
{
messages.Append( string.Format(#"ErrorCode: {0}, ErrorMessage: {1} ",msg.ErrorCode,msg.ErrorMessage));
}
}
}
errorMessage = Convert.ToString(messages);
Common.Errors.Add(new Exception(String.Format(ConfigurationManager.AppSettings["FailedEnrollErrorText"], caseNumber, errorMessage), enrollmentResponse.ErrorInformationMA.ErrorInformationPostMcaps));
taskStatus = GenerateTask(eRequest, caseNumber, false, errorMessage);
if (taskStatus)
{
UpdateTriggerStatus(caseNumber, "Y");
}
else
{
UpdateTriggerStatus(caseNumber, "N");
Common.Errors.Add(new Exception(String.Format(ConfigurationManager.AppSettings["FailedEnrollErrorText"], caseNumber, "Task Creation")));
}
}
else
{
Common.Status.Success = (Common.Status.Success + 1);
UpdateTriggerStatus(caseNumber, "Y");
}
}
else
{
enrolledIndividuals = eRequest.Select(p => new EnrolledIndividual
{
IndividualId = p.IndividualId,
EdgTraceId = p.EdgTraceId,
EDGNumber = p.EDGNumber
}).ToList();
request = new SelectedPlanPremiumDetails()
{
EmployerId = 0,
CaseNumber = caseNumber,
CallBackId = Common.ApplicationName,
SourceSystem = EnrollmentLibrary.SourceSystem.MAAUTOASSIGN,
AutoAssignMCOIndividuals = enrolledIndividuals
};
enrollmentResponse = InvokeEnrollment(request);
if (enrollmentResponse.OverallStatus == false && enrollmentResponse.ErrorInformationMA != null)
{
StringBuilder messages = new StringBuilder();
if (enrollmentResponse.ErrorInformationMA.ErrorInformationPostMcaps != null)
{
messages.Append(enrollmentResponse.ErrorInformationMA.ErrorInformationPostMcaps.Message);
Exception innerExp = enrollmentResponse.ErrorInformationMA.ErrorInformationPostMcaps.InnerException;
if (innerExp != null)
{
// messages.Append(enrollmentResponse.ErrorInformationMA.ErrorInformationPostMcaps.InnerException.Message);
do
{
messages.Append(innerExp.Message);
innerExp = innerExp.InnerException;
}
while (innerExp != null);
}
}
else
{
if (enrollmentResponse.ErrorInformationMA != null && enrollmentResponse.ErrorInformationMA.InnerErrorInfo.Count != null)
{
foreach (var msg in enrollmentResponse.ErrorInformationMA.InnerErrorInfo)
{
messages.Append(string.Format(#"ErrorCode: {0}, ErrorMessage: {1} ", msg.ErrorCode, msg.ErrorMessage));
}
}
}
errorMessage = Convert.ToString(messages);
Common.Errors.Add(new Exception(String.Format(ConfigurationManager.AppSettings["AutoEnrollErrorText"], caseNumber, errorMessage), enrollmentResponse.ErrorInformationMA.ErrorInformationPostMcaps));
}
else
{
// Update status to be saved in InterfaceSummary table.
Common.Status.Success = (Common.Status.Success + 1);
}
}
}
catch(Exception ex)
{
Common.Errors.Add(new Exception(String.Format(ConfigurationManager.AppSettings["AutoEnrollErrorText"], eRequest.Key, ex.Message), ex));
}
};
}
int dParallelism = Convert.ToInt32(ConfigurationManager.AppSettings["DegreeofParallelism"]);
Parallel.ForEach(EnrollmentRequests,
new ParallelOptions() { MaxDegreeOfParallelism = dParallelism > 0 ? dParallelism : 1 },
processRequest);

savechanges() saving one entity and not other

A weird situation has struck me this code was running successfully two days back, but i dont know why its not running as before now :
public static void ChangeStatus(int sessionID, int? participantID, Guid? temporaryParticipantID, int statustypeID)
{
using (EMSEntities entities = new EMSEntities())
using (TransactionScope ts = new TransactionScope())
{
try
{
SessionParticipant sessionParticipant = null;
CurrentSessionSeatsStatu sessionCurrentStatus = null;
if (participantID != null)
{
sessionParticipant = entities.SessionParticipants
.Where(a => a.SessionID == sessionID && a.ParticipantID == participantID)
.FirstOrDefault();
}
else if (temporaryParticipantID != null)
{
sessionParticipant = entities.SessionParticipants
.Where(a => a.SessionID == sessionID && a.TemporaryParticipantID == temporaryParticipantID)
.FirstOrDefault();
}
if (sessionParticipant != null)
{
sessionParticipant.StatusTypeID = statustypeID; // Status Changed here
}
**if (sessionParticipant.StatusTypeID == 2) // verified status
{
sessionCurrentStatus = entities.CurrentSessionSeatsStatus
.Where(a => a.SessionID == sessionID)
.FirstOrDefault();
if (sessionCurrentStatus.SeatsLeft > 0)
{
sessionCurrentStatus.SeatsLeft = sessionCurrentStatus.SeatsLeft - 1;
}
}**
entities.SaveChanges();
ts.Complete();
}
catch (Exception ex)
{
ts.Dispose();
}
}
}
The problem is that changes(in StatusTypeID) for sessionParticipant are not saved in database but sessionCurrentStatus changes are !
no error thrown nothing !
Edit: I have discovered that the change in sessionparticipant is happening in all cases except when the status is changed to verified.
ie. when the other table viz. sessioncurrentstatus is updated in the if block.
That is whenever it goes in this if block(bold in code) the problem takes place.
Finally i found the problem and i think its because of the below code however it would be good if someone can explain the exact reason:
EMS.DAL.DALHelper.AttachAndSaveChanges(sessionParticipant, System.Data.EntityState.Modified); // the position of this code line can be found in the below code
below is the code which called the ChangesStatus method:
protected void ddlStatuses_SelectedIndexChanged(object sender, EventArgs e)
{
for (int i = 0; i < gridViewEvents.VisibleRowCount; i++)
{
if (gridViewEvents.Selection.IsRowSelected(i))
{
EMS.DAL.SessionParticipant sessionParticipant = (EMS.DAL.SessionParticipant)gridViewEvents.GetRow(i);
EMS.DAL.Session session = EMS.DAL.DALHelper.GetSessionById(sessionParticipant.SessionID);
EMS.DAL.DALHelper.ChangeStatus(sessionParticipant.SessionID, sessionParticipant.ParticipantID, sessionParticipant.TemporaryParticipantID, Convert.ToInt32(ddlStatuses.SelectedItem.Value));
if (ddlStatuses.SelectedItem.Value == "2" || ddlStatuses.SelectedItem.Value == "3") // if accepted or rejected
{
if (ddlStatuses.SelectedItem.Value == "2") // verified/accepted
{
EMS.DAL.DALHelper.SendMail("Congratulations! your participation for " + session.Name + " event has been confirmed.", "", sessionParticipant.Email, "");
// AT THIS POINT THE 'sessionParticipant' did not have the changed status which was set in the ChangeStatus method
sessionParticipant.IsNotified = true;
EMS.DAL.DALHelper.AttachAndSaveChanges(sessionParticipant, System.Data.EntityState.Modified); // culprit as per me
List<EMS.DAL.SessionAttendanceList> attendanceList = EMS.DAL.DALHelper.GetSessionAttendanceList(session.ID);
attendanceList.ForEach(a =>
{
EMS.DAL.AttendanceListDetail attendanceListDetail = a.AttendanceListDetails.Where(p => p.ParticipantID == sessionParticipant.ParticipantID).FirstOrDefault();
if (attendanceListDetail == null)
{
attendanceListDetail.AttendanceListID = a.ID;
attendanceListDetail.ParticipantID = sessionParticipant.ParticipantID.Value;
attendanceListDetail.IsPresent = false;
EMS.DAL.DALHelper.AttachAndSaveChanges(attendanceListDetail, System.Data.EntityState.Added);
}
});
}
else if (ddlStatuses.SelectedItem.Value == "3") // denied/rejected
{
EMS.DAL.DALHelper.SendMail("Your participation for " + session.Name + " event has been denied.", "", sessionParticipant.Email, "");
sessionParticipant.IsNotified = true;
EMS.DAL.DALHelper.AttachAndSaveChanges(sessionParticipant, System.Data.EntityState.Modified);
List<EMS.DAL.SessionAttendanceList> attendanceList = EMS.DAL.DALHelper.GetSessionAttendanceList(session.ID);
attendanceList.ForEach(a =>
{
EMS.DAL.AttendanceListDetail attendanceListDetail = a.AttendanceListDetails.Where(p => p.ParticipantID == sessionParticipant.ParticipantID).FirstOrDefault();
if (attendanceListDetail != null)
{
EMS.DAL.DALHelper.AttachAndSaveChanges(attendanceListDetail, System.Data.EntityState.Deleted);
}
});
}
}
else
{
List<EMS.DAL.SessionAttendanceList> attendanceList = EMS.DAL.DALHelper.GetSessionAttendanceList(session.ID);
attendanceList.ForEach(a =>
{
EMS.DAL.AttendanceListDetail attendanceListDetail = a.AttendanceListDetails.Where(p => p.ParticipantID == sessionParticipant.ParticipantID).FirstOrDefault();
if (attendanceListDetail != null)
{
EMS.DAL.DALHelper.DeleteAttendanceListDetail(attendanceListDetail);
}
});
attendanceList.ForEach(a =>
{
EMS.DAL.DALHelper.DeleteSessionAttendanceList(a);
});
}
}
}
gridViewEvents.DataBind();
RefreshSeats();
}

Categories

Resources