Stackoverflow error while checking InvokeRequired - c#

I'm getting a stackverflow error while executing InvokeRequired.
System.StackOverflowException was unhandled
How to fix it?
There is no info i View Details.
FIXED VERSION:
public DialogResult ShowMessage(string msg, string caption, MessageBoxButtons buttons)
{
if (InvokeRequired)
{
Func<DialogResult> m = () => MessageBox.Show(msg, caption, buttons);
return (DialogResult)Invoke(m);
}
else
{
return MessageBox.Show(msg, caption, buttons);
}
}

It's because when InvokeRequired is true, you call the exact same method again and again. You need to use Invoke in order to get the method scheduled to run on the UI thread. In this case, InvokeRequired will be false, and your code will run into the if branch where you actually show the dialog.
Change your code to something along the lines of:
if(InvokeRequired)
{
Func<DialogResult> showMsg = () => ShowMessage(msg, caption, buttons);
return (DialogResult)Invoke(showMsg);
}

You're getting a stackoverflow because the ShowMessage method is stuck in an infinitive loop, because it calls itself over and over when "InvokeRequired"

Related

Custom Message Box displays after Message box

I have some code that when I call my CustomMessageBox it displays the box with a user prompt for an amount of my object to add, once that is done I have it added to a list of objects. Once added, it then Displays a MessageBox.Show to just let the user know it was added.
My problem is that when I run the code it executes all the code, bypasses the display of the Custom message box, then displays the MessageBox.Show, and THEN displays the CMB.Show. I ran the code through the debugger and followed the trail and it hits the CMB.Show before the MessageBox.Show, but is displayed once the code is done. Sorry, I am still learning and might not be telling the problem well, please let me know if there is anything I can further explain upon.
Some code:
private int BasicLand(Card basicLand)
{
var countBox = new TextBox
{
Name = "count",
Width = 100,
};
var cmbCount = new CustomMessageBox
{
Caption = "Blah",
Content = countBox,
RightButtonContent = "ok",
};
cmbCount.Dismissed += (s1, e1) =>
{
switch (e1.Result)
{
case CustomMessageBoxResult.RightButton:
if (int.TryParse(countBox.Text, out tempInt) && Convert.ToInt32(countBox.Text) > 0)
{
countReturn = Convert.ToInt32(tempInt);
break;
}
else
{
//Some code for error....
}
}
};
cmbCount.Show();
return countReturn;
}
Then the other part that triggers first but is last in the code block.
MessageBox.Show("Object was added to List!");
I tried adding the ShowDialog to the custom box but it came up broken in VS. BasicLand is called within another method and when the object is added to the list it will display the MessageBox.Show.
The problem with your code is, it does not take into account that any user interaction is asynchronous. When you call Show() it will actually show the messagebox, but it will not block your currently running thread, the other statements after the call to Show() will be executed immediately and thus your method returns a returnvalue that has not been provided by the user but is just the default. To fix this you have to write your code in continuations.
private void PromtUserForFeeblefezerAmount(Action<int> continueFeeblefzing, Action cancel)
{
var messagebox = CreateFeeblefezerPromt();
messagebox.Dismissed += (sender, args) =>
{
if ( args.Result == CustomMessageBoxResult.RightButton )
continueFeeblefzing( GetFeeblefezerAmount(messagebox) );
else
cancel();
};
messagebox.Show();
}

C# if statement true cancel the remaining process

I have an if statement that checks if a textbox is not empty. HOwever, if it True, meaning empty i want it to cancel the rest of the process and go back to my form. Below is the IF statement that i have, i cant figure out how to Cancel the remainder of the process.
if (textBox2.Text.Equals(""))
{
MessageBox.Show("Field is Empty", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
Calling a method like
DoSomething();
causes it to start executing whatever is inside. In some point, if you no longer wish to continue in execution of that method call, use return statement with no return value for methods returning void or return something for methods with non-void return type, where something is type of the return type.
public void DoSomething()
{
... do something
if (condition)
return; // returns from a method call
}
http://msdn.microsoft.com/fr-fr/library/1dac1663%28v=vs.80%29.aspx
private void validateUserEntry2()
{
// Checks the value of the text.
if(serverName.Text.Length == 0)
{
// Initializes the variables to pass to the MessageBox.Show method.
string message = "You did not enter a server name. Cancel this operation?";
string caption = "No Server Name Specified";
MessageBoxButtons buttons = MessageBoxButtons.YesNo;
DialogResult result;
// Displays the MessageBox.
result = MessageBox.Show(this, message, caption, buttons,
MessageBoxIcon.Question, MessageBoxDefaultButton.Button1,
MessageBoxOptions.RightAlign);
if(result == DialogResult.Yes)
{
// Closes the parent form.
this.Close();
}
}
}

Showing MessageBox in long running process

In an MVVM application I have a long running calculation that runs
in legacy code.
That legacy code shows a MessageBox to ask the user if it shall continue.
Now I want this code to stick to MVVM as easy as possible and thought
about handing in a callback to show the MessageBox and evaluating the
result inside.
How can this be done the easiest?
Have often seen Action for callbacks, but I have no idea how
to work with the bool inside the legacy code.
I want to pass the string to show in the MessageBox from the legacy code
and return the decision (a bool) to the legacy code.
Please note: I do not have to do a bigger refactoring right now, but want
to get rid of the MessageBox inside the legacy code right now.
Perhaps I can use a function like
private bool ShowMessageBox(string text)
{
var result = MessageBox.Show(text, "", MessageBoxButton.YesNo);
if (result.Equals(MessageBoxResult.Yes))
{
return true;
}
return false;
}
-edit-
Should I use some
Action<string, Action<bool>>
for the method signature?
How can I access the bool in the legacy code?
Maybe you can use a delegate?
For the method you showed, you can create a delegate like this:
public delegate bool ShowMessageBoxDelegate(string text);
Then let's say you have a property using the delegate as the type:
public ShowMessageBoxDelegate ShowMessageBoxDelegateProperty { get; set; }
Now if your ShowMessageBox method matches the signature of this delegate...
public bool ShowMessageBox(string text)
{
var result = MessageBox.Show(text, "", MessageBoxButton.YesNo);
if (result.Equals(MessageBoxResult.Yes))
{
return true;
}
return false;
}
... then you could set it as the value of the ShowMessageBoxDelegateProperty property:
ShowMessageBoxDelegateProperty = ShowMessageBox;
Note the missing parenthesis. A delegate can also be multicast, which simply means that they can have more than one method attached to them:
ShowMessageBoxDelegateProperty += ShowMessageBox;
You can also use them as parameters in methods:
public void ProxyShowMessageBox(ShowMessageBoxDelegate showMessageBoxDelegate)
{
if (showMessageBoxDelegate != null)
{
bool result = showMessageBoxDelegate("MessageBox message");
}
}
You would then call it like this:
ProxyShowMessageBox(ShowMessageBox);
You can find out more from the Delegates Tutorial page at MSDN.

Back Button/ Cancel Button during In App Purchase

I am having trouble detecting the Exception that is thrown by the in-app-purchase store during Unit Test (Beta app) for Windows Phone 8 when I press the Cancel or Back button on the phone. The app simply exits.
There are no errors when I use the MockIAP. Cancel or Back Button returns an empty receipt variable during the await receipt = Store... It is handled correctly in MockIAP. But apparently Unit Test and the real app Store handleds Cancel or Back events differently. The app simply exits, which I believe because it is throwing an unhandled error.
My app is a Phonegap 2.3 and the purchase part is handled by the plugin. Unlike the MockIAP, I can't see (i.e. attach break points) what is happening on the wrapper side when Cancel or Back button is pressed during purchase. I have tried showing MessageBox.Show for every step of the purchase. The MessageBox.Show code is working when I press confirm purchase but not when I press Cancel or Back Button. I have made it synchronous already with EventWaitHandle.
In addition, I have set e.Handled = true for the unhandled Exception event to try to stop it from exit the app with no luck.
From online, my purchase code is boilerplate, so I dont' understand why other people hasn't come across this problem before, and why there are no solutions online. Does anyone have any idea how to fix this?
Purchase.cs (Plugin):
private static string receipt;
private async void purchaseProduct()
{
bool canBuy = false;
try
{
li = await Store.CurrentApp.LoadListingInformationAsync();
if (li.ProductListings.ContainsKey(package_id))
{
canBuy = true;
EventWaitHandle Wait = new AutoResetEvent(false);
Deployment.Current.Dispatcher.BeginInvoke(async () =>
{
// Here is the problem.. Don't know what is passed back to receipt when Cancel or Back is pressed, which is causing the app to close during Unit Test but not MockIAP
receipt = await Store.CurrentApp.RequestProductPurchaseAsync(package_id, true);
receipt = receipt.ToString();
Wait.Set();
});
Wait.WaitOne();
}
}
catch(Exception e)
{
var eMsg = e.Message.ToString();
errorMsg("Catch Exception: ", eMsg);
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
}
finally
{
errorMsg("Receipt with await: ", receipt);
if (canBuy && receipt!= "")
{
errorMsg("Hitting the parsing", "");
parseXML(receipt);
prepData();
httpPostData();
Store.CurrentApp.ReportProductFulfillment(package_id);
}
else
{
errorMsg("Else Finally", "");
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
}
}
}
private static void errorMsg(String caption, String msg)
{
EventWaitHandle Wait = new AutoResetEvent(false);
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show(caption + msg);
Wait.Set();
});
Wait.WaitOne();
}
App.cs
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
Exception ex = (Exception)e.ExceptionObject;
EventWaitHandle Wait = new AutoResetEvent(false);
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("Unhandled Exception: " + ex.Message);
Wait.Set();
});
Wait.WaitOne();
// Stop from exiting..
e.Handled = true;
if (System.Diagnostics.Debugger.IsAttached)
{
// An unhandled exception has occurred; break into the debugger
//System.Diagnostics.Debugger.Break();
}
}
to fix this enclose try/catch around RequestProductPurchaseAsync method call even though you had a try/catch for entire method...
try
{
receipt = await CurrentApp.RequestProductPurchaseAsync("MyItem", false);
}
catch (Exception){}
.... other code

How to call window.alert("message"); from C#?

I have my own exception based on some condition and want to raise an alert when control comes in this catch block
catch (ApplicationException ex)
{
//want to call window.alert function here
}
Do you mean, a message box?
MessageBox.Show("Error Message", "Error Title", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
More information here: http://msdn.microsoft.com/en-us/library/system.windows.forms.messagebox(v=VS.100).aspx
It's a bit hard to give a definitive answer without a bit more information, but one usual way is to register a startup script:
try
{
...
}
catch(ApplicationException ex){
Page.ClientScript.RegisterStartupScript(this.GetType(),"ErrorAlert","alert('Some text here - maybe ex.Message');",true);
}
if you are using ajax in your page that require script manager Page.ClientScript
will not work,
Try this and it would do the work:
ScriptManager.RegisterClientScriptBlock(this, GetType(),
"alertMessage", #"alert('your Message ')", true);
You can use the following extension method from any web page or nested user control:
static class Extensions
{
public static void ShowAlert(this Control control, string message)
{
if (!control.Page.ClientScript.IsClientScriptBlockRegistered("PopupScript"))
{
var script = String.Format("<script type='text/javascript' language='javascript'>alert('{0}')</script>", message);
control.Page.ClientScript.RegisterClientScriptBlock(control.Page.GetType(), "PopupScript", script);
}
}
}
like this:
class YourPage : Page
{
private void YourMethod()
{
try
{
// do stuff
}
catch(Exception ex)
{
this.ShowAlert(ex.Message);
}
}
}
You can also do this :
catch (Exception ex)
{
ScriptManager.RegisterStartupScript(Page, Page.GetType(), "showError",
"alert('" + ex.Message + "');", true);
}
this will show the exeption message in the alert box
MessageBox like others said, or RegisterClientScriptBlock if you want something more arbitrary, but your use case is extremely dubious. Merely displaying exceptions is not something you want to do in production code - you don't want to expose that detail publicly and you do want to record it with proper logging privately.
I'm not sure if I understand but I'm guessing that you're trying to show a MessageBox from ASP.Net?
If so, this code project article might be helpful: Simple MessageBox functionality in ASP.NET
Simple use this to show the alert message box in code behind.
ScriptManager.RegisterStartupScript(this, this.GetType(), "script", "alert('Record Saved Sucessfully');", true);
You can try this:
Hope it works for you..
`private void validateUserEntry()
{
// Checks the value of the text.
if(serverName.Text.Length == 0)
{
// Initializes the variables to pass to the MessageBox.Show method.
string message = "You did not enter a server name. Cancel this operation?";
string caption = "Error Detected in Input";
MessageBoxButtons buttons = MessageBoxButtons.YesNo;
DialogResult result;
// Displays the MessageBox.
result = MessageBox.Show(message, caption, buttons);
if (result == System.Windows.Forms.DialogResult.Yes)
{
// Closes the parent form.
this.Close();
}
}
}`
You should try this.
ClientScript.RegisterStartupScript(this.GetType(), "myalert", "alert('Sakla Test');", true);

Categories

Resources