I have a C# service that runs continuously with user credentials (i.e not as localsystem - I can't change this though I want to). For the most part the service seems to run ok, but ever so often it bombs out and restarts for no apparent reason (servicer manager is set to restart service on crash).
I am doing substantial event logging, and I have a layered approach to Exception handling that I believe makes at least some sort of sense:
Essentially I got the top level generic exception, null exception and startup exception handlers.
Then I got various handlers at the "command level" (i.e specific actions that the service runs)
Finally I handle a few exceptions handled at the class level
I have been looking at whether any resources aren't properly released, and I am starting to suspect my mailing code (send email). I noticed that I was not calling Dispose for the MailMessage object, and I have now rewritten the SendMail code as illustrated below.
The basic question is:
will this code properly release all resources used to send mails?
I don't see a way to dispose of the SmtpClient object?
(for the record: I am not using object initializer to make the sample easier to read)
private static void SendMail(string subject, string html)
{
try
{
using ( var m = new MailMessage() )
{
m.From = new MailAddress("service#company.com");
m.To.Add("user#company.com");
m.Priority = MailPriority.Normal;
m.IsBodyHtml = true;
m.Subject = subject;
m.Body = html;
var smtp = new SmtpClient("mailhost");
smtp.Send(m);
}
}
catch (Exception ex)
{
throw new MyMailException("Mail error.", ex);
}
}
I know this question is pre .Net 4 but version 4 now supports a Dispose method that properly sends a quit to the smpt server. See the msdn reference and a newer stackoverflow question.
There are documented issues with the SmtpClient class. I recommend buying a third party control since they aren't too expensive. Chilkat makes a decent one.
Related
In my Grails application, there is a requirement to allow different text to be shown to users on a per 'organisation' basis, but to fall back to reading the text from messages.properties if no overriding text is defined for an organisation.
I'm using an approach similar to the one detailed here, which works well in the scope of an http request, however I now also need to define email content on a per organisation basis which is a bit problematic as emails are sent asynchronously (using the async mail plugin). My current resolveCode() implementation looks like this:
public MessageFormat resolveCode(String code, Locale locale) {
Message msg = null
try {
Organisation currentOrganisation = currentOrganisationSessionProxy.currentSessionOrganisation
msg = Message.findByCodeAndLocaleAndOrganisation(code, locale, currentOrganisation)
} catch (Exception e) {
//handle exception
}
def format
if (msg) {
format = new MessageFormat(msg.text, msg.locale)
} else {
format = messageBundleMessageSource.resolveCode(code, locale)
}
return format
}
I've modified the DatabaseMessageSource implementation slightly as I need to resolve the current 'session' organisation using a session-scoped proxy.
Can anyone suggest a good approach for sending localized, organisation-specific emails asynchronously? I guess I would need to persist the organisation id along with the email, and then retrieve it some how in my DatabaseMessageSource. Any help is appreciated.
This actually turned out to be simpler than I thought. I didn't need to modify the async mail plugin, but I did need to override the ValidationTagLib g:message implementation so that I could pass in an organisationId. I also needed to provide alternate implementations of AbstractMessageSource.getMessage methods that also took an organisationId argument.
I Implemented a HttpListener to process SoapRequests. This works fine but I can't find a soloution for the problem, that some soap-requests take too much time, resulting in timeouts on client side.
How do I let the requesting client know, that his request is not a timeout?
I thought about sending "dummy"-information while the request gets processsed, but the HttpListener only seems to send the data when you Close the response-object, and this can be done only once, so this is not the right thing to do I suppose.
Soloution:
Thread alliveWorker = new Thread(() =>
{
try
{
while (context.Response.OutputStream.CanWrite)
{
context.Response.OutputStream.WriteByte((byte) ' ');
context.Response.OutputStream.Flush();
Thread.Sleep(5000);
}
}
finally
{
}
});
alliveWorker.Start();
doWork();
alliveWorker.Interrupt();
createTheRealResponse();
Sending dummy information is not a bad idea.
I think you need to call the Flush() method on the HttpListenerResponse's OutputStream property after writing the dummy data. You must also enable SendChunked property:
Try sending a dummy space at regular interval:
response.SendChunked = true;
response.OutputStream.WriteByte((byte)' ');
response.OutputStream.Flush();
I see two options - increase timeouts on client side or extend protocol with operation status requests from client for long running operations.
If you are using .net 4.5, take a look at the HttpListenerTimeoutManager Class, you can use this class as a base to implement custom timeout behaviour.
Using JAX-WS 2, I see an issue that others have spoken about as well. The issue is that if a SOAP message is received inside a handler, and that SOAP message is large - whether due to inline SOAP body elements that happen to have lots of content, or due to MTOM attachments - then it is dangerously easy to get an OutOfMemoryError.
The reason is that the call to getMessage() seems to set off a chain of events that involve reading the entire SOAP message on the wire, and creating an object (or objects) representing what was on the wire.
For example:
...
public boolean handleMessage(SOAPMessageContext context)
{
// for a large message, this will cause an OutOfMemoryError
System.out.println( context.getMessage().countAttachments() );
...
My question is: is there a known mechanism/workaround for dealing with this? Specifically, it would be nice to access the SOAP part in a SOAP message without forcing the attachments (if MTOM for example) to also be vacuumed up.
For those who run their app on JBoss 6 & 7 (with Apache CXF)... I was able to troubleshoot the problem by implementing my handler from the LogicalHandler interface instead of the SOAPHandler.
In this case your handleMessage() method would get the LogicalMessageContext context (instead of SOAPMessageContext) in the arguments that has no issues with the context.getMessage() call
There's actually a JAX-WS RI (aka Metro) specific solution for this which is very effective.
See https://javaee.github.io/metro/doc/user-guide/ch02.html#efficient-handlers-in-jax-ws-ri. Unfortunately that link is now broken but you can find it on WayBack Machine. I'll give the highlights below:
The Metro folks back in 2007 introduced an additional handler type, MessageHandler<MessageHandlerContext>, which is proprietary to Metro. It is far more efficient than SOAPHandler<SOAPMessageContext> as it doesn't try to do in-memory DOM representation.
Here's the crucial text from the original blog article:
MessageHandler:
Utilizing the extensible Handler framework provided by JAX-WS
Specification and the better Message abstraction in RI, we introduced
a new handler called MessageHandler to extend your Web Service
applications. MessageHandler is similar to SOAPHandler, except that
implementations of it gets access to MessageHandlerContext (an
extension of MessageContext). Through MessageHandlerContext one can
access the Message and process it using the Message API. As I put in
the title of the blog, this handler lets you work on Message, which
provides efficient ways to access/process the message not just a DOM
based message. The programming model of the handlers is same and the
Message handlers can be mixed with standard Logical and SOAP handlers.
I have added a sample in JAX-WS RI 2.1.3 showing the use of
MessageHandler to log messages and here is a snippet from the sample:
public class LoggingHandler implements MessageHandler<MessageHandlerContext> {
public boolean handleMessage(MessageHandlerContext mhc) {
Message m = mhc.getMessage().copy();
XMLStreamWriter writer = XMLStreamWriterFactory.create(System.out);
try {
m.writeTo(writer);
} catch (XMLStreamException e) {
e.printStackTrace();
return false;
}
return true;
}
public boolean handleFault(MessageHandlerContext mhc) {
.....
return true;
}
public void close(MessageContext messageContext) { }
public Set getHeaders() {
return null;
}
}
(end quote from 2007 blog post)
You can find a full example in the Metro GitHub repo.
What JAX-WS implementation runtime are you using? If there's a way to do this using the runtime built into WebSphere I'm certain there's a way to do this cleanly in other runtimes like Axis2 (proper), Apache CXF, and Metro/RI.
I am using the other way to reduce the memory costing, which is Message Accessor.
Instead of using context.getMessage(), I changed it to this way:
Object accessor = context.get("jaxws.message.accessor");
if (accessor != null) {
baosInString = accessor.toString();
}
Base on advice from IBM website. http://www-01.ibm.com/support/docview.wss?uid=swg1PM21151
I have a little Android application in which I specify my application directly and do some application-wide setup in the ApplicationSubclass' onCreate, but I am getting the following error (Note, I know about FLAG_ACTIVITY_NEW_TASK):
Caused by: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
at android.app.ContextImpl.startActivity(ContextImpl.java:644)
at android.content.ContextWrapper.startActivity(ContextWrapper.java:258)
at somePart.ofA.nameSpace.ApplicationSubclass.sendNotificationEmail(ApplicationSubclass.java:186)
I am calling this sendNotificationEmail when some exceptions are thrown and I catch them, so that the user of the app can send in a little e-mail with information on the exception so that I can more easily fix anything that might arise or guide them on fixing their issue.
Here is some of the relevant code:
manifest.xml:
<application android:label="#string/app_name" android:icon="#drawable/icon" android:name=".ApplicationSubclass">
// ... some stuff, including all of my app's activities
</application>
the ApplicationSubclass is defined as:
public class ApplicationSubclass extends Application {
// Multiple methods, including an override of onCreate
public void sendNotificationEmail(String emailBody) {
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
emailIntent.setType("text/html");
emailIntent.putExtra(Intent.EXTRA_EMAIL, notificationRecipients);
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "MyAppName Error");
emailIntent.putExtra(Intent.EXTRA_TEXT, emailBody);
try {
startActivity(Intent.createChooser(emailIntent, "An error has occurred! Send an error report?"));
} catch (ActivityNotFoundException e) {
// If there is nothing that can send a text/html MIME type
e.printStackTrace();
}
}
}
I'd like to know why this is happening. I read some documentation, I looked for some answers on StackOverflow and the Internet at large. It seems to me that I should be fine since I am setting FLAG_ACTIVITY_NEW_TASK, however that's clearly not the case!
Is it simply that I may not even attempt to do this from the Application's context? Must I be within a Activity in my application when I attempt this? It would be sort of annoying to need to re-engineer around this, and being able to send exception e-mails would be quite useful!
EDIT: Rich asked a good question, and that's why the heck would I want to be doing this in the first place? The answer is simply that there is data being loaded in the Application that could fail, and I'd like the user to be able to send some of that failure data when this occurs.
The reason this is in the Application and not the activity is that there are application state variables I don't want to lose every time someone rotates the device. When I found out about the fact that onPause and onCreate are called when you rotate (for Activies) I refactored this code out into the Application (which works great!). I had actually tried the solution to send these to onConfigurationChanged and Override that method in my activity, but that's messy and for whatever reason despite putting android:configChanges="keyboardHidden|orientation" in my manifest it wasn't correctly working for me. I'm sure I could pursue this option, but I'd rather leave things as they are (it's cleaner) and get the ability for someone to e-mail!
Ah! I figured out what I did, it's quite simple! I was setting the FLAG_ACTIVITY_NEW_TASK on the wrong intent! Silly me, I missed that Intent.createChooser(...,...) will return a new Intent, so you must set the flag on the chooser Intent rather than on the ACTION_SEND Intent.
Not all that confusing when you think about it, and I can't believe I overlooked that!
So if anyone ever does what I did, here you go:
public void sendNotificationEmail(String emailBody) {
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setType("text/html");
emailIntent.putExtra(Intent.EXTRA_EMAIL, notificationRecipients);
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "MyAppName Error");
emailIntent.putExtra(Intent.EXTRA_TEXT, emailBody);
Intent emailChooser = Intent.createChooser(emailIntent, "An error has occurred! Send an error report?");
emailChooser.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
startActivity(emailChooser);
} catch (ActivityNotFoundException e) {
// If there is nothing that can send a text/html MIME type
e.printStackTrace();
}
}
I have launch an activity(to relogin the user when loss the session) from my class which subclass from Application as follow:
public boolean relogin(Activity act) {
Intent intent = new Intent(act,ActivityLogin.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
act.finish();// here i finish my current activity
}
The preamble
We're implementing a MVC2 site that needs to consume an external API via https (We cannot use WCF or even old-style SOAP WebServices, I'm afraid). We're using AsyncController wherever we need to communicate with the API, and everything is running fine so far.
Some scenarios have come up where we need to make multiple API calls in series, using results from one step to perform the next.
The general pattern (simplified for demonstration purposes) so far is as follows:
public class WhateverController : AsyncController
{
public void DoStuffAsync(DoStuffModel data)
{
AsyncManager.OutstandingOperations.Increment();
var apiUri = API.getCorrectServiceUri();
var req = new WebClient();
req.DownloadStringCompleted += (sender, e) =>
{
AsyncManager.Parameters["result"] = e.Result;
AsyncManager.OutstandingOperations.Decrement();
};
req.DownloadStringAsync(apiUri);
}
public ActionResult DoStuffCompleted(string result)
{
return View(result);
}
}
We have several Actions that need to perform API calls in parallel working just fine already; we just perform multiple requests, and ensure that we increment AsyncManager.OutstandingOperations correctly.
The scenario
To perform multiple API service requests in series, we presently are calling the next step within the event handler for the first request's DownloadStringCompleted. eg,
req.DownloadStringCompleted += (sender, e) =>
{
AsyncManager.Parameters["step1"] = e.Result;
OtherActionAsync(e.Result);
AsyncManager.OutstandingOperations.Decrement();
}
where OtherActionAsync is another action defined in this same controller following the same pattern as defined above.
The question
Can calling other async actions from within the event handler cause a possible race when accessing values within AsyncManager?
I tried looking around MSDN but all of the commentary about AsyncManager.Sync() was regarding the BeginMethod/EndMethod pattern with IAsyncCallback. In that scenario, the documentation warns about potential race conditions.
We don't need to actually call another action within the controller, if that is off-putting to you. The code to build another WebClient and call .DownloadStringAsync() on that could just as easily be placed within the event handler of the first request. I have just shown it like that here to make it slightly easier to read.
Hopefully that makes sense! If not, please leave a comment and I'll attempt to clarify anything you like.
Thanks!
It turns out the answer is "No".
(for future reference incase anyone comes across this question via a search)