After WCFService call End Further code does not execute on Client side - c#

I want to show a message box on client side When a call is returned from service.
It is confirmed service runs and saves data into Database but call does not return.
I Google it but did not find a way
Here is my client code
private void button1_Click(object sender, EventArgs e)
{
try {
string ide = txt_id.Text;
int id = int.Parse(ide);
string city = txt_city.Text;
Service1Client client = new Service1Client();
if (client.insert(id, city))
{
client.Close();
MessageBox.Show("Your changes were saved");
}
}
catch(Exception ex)
{
Console.WriteLine(ex);
}
}
Service code
public bool insert(int id,string city)
{
Ship s = new Ship
{
order_id = id,
shipcity = city,
order_date = DateTime.Now
};
ShipsDataContext od = new ShipsDataContext();
od.Ships.InsertOnSubmit(s);
try
{
od.SubmitChanges();
Console.ReadKey();
return true;
}
catch (Exception ex)
{
Console.WriteLine(ex);
return false;
}
}

You are waiting for console input:
Console.ReadKey();
Btw, that error handling is a problem because you are suppressing bugs (by discarding all error information) and in case of error you do nothing.

Related

Signal R reconnect seems to create a new thread

We have a siglnalR hub hosted in IIS, and a WPF .net core application that connects. Everything is working perfectly on first run. However, when IIS recycles the application pool, the WPF client re-reconnects successfully, but, (so it seems) on another thread, as when the user attempts to perform an action (open a new WPF window) - the following error is thrown when creating a new instance of the window to open :-
"The calling thread must be STA, because many UI components require this"
This is how we connect to the hub :-
private async void Connect()
{
try
{
_signalRConnection.On<Notification>(NotificationMessageStr, (message) =>
{
if (message != null && _signalRConnection != null)
{
OnProcessMessage(message);
}
}
);
_signalRConnection.Reconnecting += error =>
{
OnReconnecting("Connection lost - Attempting to reconnect.");
return Task.CompletedTask;
};
_signalRConnection.Reconnected += connectionId =>
{
OnReconnected("Reconnected");
return Task.CompletedTask;
};
_signalRConnection.Closed += error =>
{
OnLostConnection("Failed to connect");
// Notify users the connection has been closed or manually try to restart the connection.
return Task.CompletedTask;
};
try
{
//Connect to the server
await _signalRConnection.StartAsync();
}
catch (Exception ex)
{
}
}
catch (Exception ex)
{
}
}
When a message is received from the hub, we call :-
private void SubscriveToNewNotification()
{
vm.NewNotification += (sender, e) => {
ShowNotificationAlert(e.NotificationMessage); };
}
private void ShowNotificationAlert(Notification notification) {
NotificationAlert notificationAlert = new NotificationAlert();
notificationAlert.notification = notification;
notificationAlert.Show();
}
And it is this:-
NotificationAlert notificationAlert = new NotificationAlert();
That is failing.
This is how the connection is built up :-
private void InitializeViewModel()
{
try
{
string serviceAddress = "xxxx/notificationHub";
connectHub = NotificationHubManager.CreateNotificationHub(serviceAddress, userInfo);
}
catch (System.Exception ex)
{
System.Windows.MessageBox.Show(ex.Message + "--");
}
connectHub.ProcessMessage += (sender, e) =>
{
// THIS IS WHERE IT FALLS OVER
NotificationAlert n = new NotificationAlert();
OnNotificationReceived(e.NotificationMessage);
};
-- This is the notification hub
public static NotificationHubConnect CreateNotificationHub(string address, ISwiftUser userInfo = null)
{
HubConnection hubConnection = new HubConnectionBuilder()
.WithUrl(address)
.WithAutomaticReconnect()
.Build();
try
{
var result = new NotificationHubConnect(hubConnection, userInfo);
return result;
}
catch (Exception ex)
{
throw ex;
}
}
Is there a way to have the reconnect run on the same thread?

UI suppression - client stuck at SigningIn state

I try to sign in to Skype For Business via my application.
When I'm with UI on, I can sign in.
When I set UI Suppression, my client is stuck at the signing in the state. Neither credentials event nor SigninCallback event nor SignInDelayed event is fired.
Can you help me?
Here is my code:
public void StartUpSkype()
{
try
{
_LyncClient = LyncClient.GetClient();
if (_LyncClient == null)
{
throw new Exception("Unable to obtain client interface");
}
if (_LyncClient.InSuppressedMode == true)
{
if (_LyncClient.State == ClientState.Uninitialized)
{
Object[] _asyncState = { _LyncClient };
_LyncClient.BeginInitialize(InitializeCallback, _asyncState);
}
}
_LyncClient.SignInDelayed += _LyncClient_SignInDelayed;
_LyncClient.StateChanged += _Client_ClientStateChanged;
_LyncClient.CredentialRequested += _LyncClient_CredentialRequested;
}
catch (NotStartedByUserException h)
{
DisplayErrorMessage("Lync is not running");
}
catch (Exception ex)
{
DisplayErrorMessage("General Exception");
}
}
void _Client_ClientStateChanged(Object source, ClientStateChangedEventArgs data)
{
if (data != null)
{
if (data.NewState == ClientState.SignedIn)
{
DisplayErrorMessage("Signed in");
UserIsSignedIn?.Invoke(_LyncClient);
}
if (data.NewState == ClientState.SignedOut)
{
string login = ConfigurationManager.AppSettings["loginSkypeClient"];
string password = ConfigurationManager.AppSettings["pwdSkypeClient"];
_LyncClient.SignInConfiguration.ForgetMe(login);
try
{
// starts the sign in process asynchronously
IAsyncResult asyncResult = _LyncClient.BeginSignIn(login, login, password, SigninCallback, _LyncClient);
// But wait for the results because the events cannot be registered within a worker thread.
asyncResult.AsyncWaitHandle.WaitOne();
}
catch (Exception e)
{
throw e;
}
}
}
}
void _LyncClient_CredentialRequested(object sender, CredentialRequestedEventArgs e)
{
string login = ConfigurationManager.AppSettings["loginSkypeClient"];
string password = ConfigurationManager.AppSettings["pwdSkypeClient"];
if (e.Type == CredentialRequestedType.SignIn)
{
e.Submit(login, password, false);
}
}
private void SigninCallback(IAsyncResult ar)
{
if (ar.IsCompleted == true)
{
try
{
((LyncClient)ar.AsyncState).EndSignIn(ar);
}
catch (RequestCanceledException re)
{
throw re;
}
}
}
private void InitializeCallback(IAsyncResult ar)
{
if (ar.IsCompleted == true)
{
object[] asyncState = (object[])ar.AsyncState;
((LyncClient)asyncState[0]).EndInitialize(ar);
//_ThisInitializedLync is part of application state and is
//a class Boolean field that is set to true if this process
//initialized Lync.
_ThisInitializedLync = true;
}
}
The login + password are correct because I can sign in with them when the UI is on.
The problem only happens when the UI is suppressed.
I've tried many things, I am desperate right now.
Please check the version of SkypeForBusiness. If it is 2016 then it is happening due to ModernAuthentication enabled on both client and tenant office365.
In case ModernAuthentication is enabled, the LyncSDK is not capable enough to handle ModernAuth as SDK doesn't support and Microsoft has no plans to upgrade the SDK.

Splitting data access and catching data to form

In my project I'm trying to write code that will be nice to understand.
I currently split my data access functions in a seperate class.
What I'm trying to achieve however, is to catch the errors back to my form. I am not getting this currently and I was wondering why.
In my form I have the following code:
private void btn_Save_ItemClick(object sender, ItemClickEventArgs e)
{
if (dal.updatePerson(ObjectAfterSaving))
{
MessageBox.Show("Updated!");
}
else
{
MessageBox.Show("error");
};
}
In my dal object (derived from the DataAccess_Person class), I have the following method:
public bool updatePerson(Person p)
{
conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["Database"].ConnectionString);
SqlCommand command = new SqlCommand(#"UPDATE Person
SET PersonName = #PersonName
WHERE PersonID = #PersonID", conn);
command.Parameters.Add("#PersonName", SqlDbType.VarChar).Value = p.Name
{
try
{
if (conn.State == ConnectionState.Closed)
{
conn.Open();
}
int a = command.ExecuteNonQuery();
conn.Close();
if (a > 0)
{
return true;
}
else
{
return false;
}
}
catch (SqlException ex)
{
ex.ToString();
return false;
}
}
}
My question is: let's say if my method falls in the catch. Will my front end (form) show it (Sql Exception for example) ? Or will i just get 'error' ? And If I will just get error, how I can improve my code to show the Exception instead of error?
A simple way is to remove the try catch from your DAL and add it to the form. For example:
private void btn_Save_ItemClick(object sender, ItemClickEventArgs e)
{
var result = "Success";
try
{
dal.updatePerson(ObjectAfterSaving);
}
catch (SqlException sqlEx)
{
result = sqlEx.Message;
}
catch (Exception ex)
{
result = ex.Message;
}
MessageBox.Show(result);
}
Just note that there's a lot of ways you can do this. My preference is to not include DAL specific exception types in my UI. Instead I may return a custom result type that has an errorcode and message and let my UI display that or generate a custom message based on the error code.
You‘ll just get „error“ in case of a SqlException. All other exceptions will crash your program if you don‘t have a global exception handler. If you want to show the error message you could introduce an out variable for the error message:
bool successful = MyMethod(out string errorMessage)
if (!successful)
{
MessageBox.Show(errorMessage);
}
public bool MyMethod(out string errorMessage)
{
errorMessage = "";
try
{
// do some stuff
return true;
}
catch(Exception ex)
{
errorMessage = ex.Message;
return false;
}
}

Check my SQL connection every second without freezing

First of all, I apologize for my English.
I have a method to verify my connection to SQL (TestConneccion), and I use a timer to verify it every second.
The problem is when I lose the connection, my application hangs while it tries to connect. I'm using task to avoid this, but I am new to C#.
I would really appreciate the help
public string testConeccion()
{
var archivo = "";
try
{
odb = DatabaseFactory.CreateDatabase("TESTCONECTION");
ocn = odb.CreateConnection();
if (ocn.State == ConnectionState.Closed)
{
ocn.Open();
}
ocn.Close();
archivo = "true";
}
catch (InvalidOperationException ex)
{
archivo = ex.Message;
}
catch (Exception ex)
{
archivo = ex.Message;
}
finally
{
ocn.Close();
}
return archivo;
}
private void timerMesas_Tick(object sender, EventArgs e)
{
Task<string> T1 = Task.Run<string>(() => oClasePublica.testConeccion());
if (T1.Result == "true")
{
btnEstado.Image = new System.Drawing.Bitmap(TOUCHREST.Properties.Resources.Status_32x32);
}
else
{
btnEstado.Image = new System.Drawing.Bitmap(TOUCHREST.Properties.Resources.Warning_32x32);
}
}
Make your timer tick handler async and await your task. This will run the method asynchronously and prevent the rest of your application from hanging while it runs.
private async void timerMesas_Tick(object sender, EventArgs e)
{
string T1 = await Task.Run<string>(() => oClasePublica.testConeccion());
if (T1 == "true")
{
btnEstado.Image = new System.Drawing.Bitmap(TOUCHREST.Properties.Resources.Status_32x32);
}
else
{
btnEstado.Image = new System.Drawing.Bitmap(TOUCHREST.Properties.Resources.Warning_32x32);
}
}
The ocn.Close() in the try code is not needed because the finally will do it. Also catch (InvalidOperationException ex) is not needed because catch (Exception) covers it.
You cannot do Task.Run and then immediately test the Result because the task has not yet finished! Normally you use Task.Wait(); however this will then block your main thread.
I suggest using a BackgroundWorker that continuously checks the connection and then reports it progress. This avoids the issue of changing the image on a non-UI thread.

Handle Multiple Incoming Data

I'm creating a UI that uses rabbitmq to receive multiple lists of type 'StorageMessage'. I'm using a background worker to merge all the data from the lists into a datatable and I bind to the gridview in the UI. I have put the method that receives the messages below, my problem is that the UI doesn't display all the data I expect it to. I'm guessing its because the background work is busy when the message comes in. Whats the correct approach to deal with these types of situations?
public void OnMessageArrived(MessageArrivedEventArgs<object> args)
{
var topicName = args.MessagingParticipant.TopicName;
if (_logger.IsInfoEnabled)
_logger.InfoFormat("Message Received from {0}", topicName);
try
{
if (args.To == _uniqueId.ToString() || args.To.EqualsOrdinalIgnoreCase("all"))
{
lock (_lock)
{
var receivedMessage = Serialization.FromJsonString<StorageMessage>(args.MessageBody);
if (!backgroundWorker1.IsBusy)
{
backgroundWorker1.RunWorkerAsync(receivedMessage);
}
}
}
}
catch (Exception exception)
{
_logger.Error("An error occurred whilst processing the received message.", exception);
}
}
The RunWorkComplete Code looks lie
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
try
{
var res = e.Result as DataTable;
_storageDataTable = ReorderTable(res, "Date", "Factor", "Aldbrough", "Holford", "Humbly Grove", "Stublach", "Holehouse Farm", "Hatfield Moor", "Hornsea", "Hill Top", "Rough", "South Hook", "Isle Of Grain", "Dragon");
UpdateDataTable();
}
catch (Exception ex)
{
}
}
And the updateDataTable code is:
private void UpdateDataTable()
{
try
{
if (InvokeRequired)
{
BeginInvoke(new MethodInvoker(() => UpdateDataTable()));
}
else
{
radGridView1.SuspendLayout();
radGridView1.GroupDescriptors.Clear();
radGridView1.DataSource = null;
radGridView1.DataSource = _storageDataTable;
radGridView1.GroupDescriptors.Add("Factor", ListSortDirection.Ascending);
// radGridView1.MasterTemplate.AutoExpandGroups = true;
radGridView1.Refresh();
radGridView1.ResumeLayout(true);
}
}
catch (Exception exception)
{
_logger.Error("Encountered an error while updating the data table.", exception);
}
}
Thanks
Elias

Categories

Resources