Sending email with EWS API very slow - c#

My code below is performing very poorly. I used the .Net StopWatch class to find out what piece of code was causing the slowness.
This line seems to be the issue:
message.SendAndSaveCopy();
E.G batch of 20 emails: 1st email takes around 2 seconds to send and this time gradually increases until the 20th email, which takes up-to 18 seconds.
public int SendBulkMarketing(bool CheckDelivery)
{
int iCounter = 0;
DataTable dt = null;
try
{
DeliveryReportDAL myDeliveryReportDAL = new DeliveryReportDAL();
dt = myDeliveryReportDAL.GetListMessageToSend('E');
if (dt == null) return iCounter;
iCounter = dt.Rows.Count;
}
catch (Exception ex)
{
new Util().LogError(ex, "SMTP:: SendBulkMarketing 1st catch");
return 0;
}
if (iCounter > 0)
{
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
service.Credentials = new WebCredentials(Account_UserName, Account_Password, Account_Domain);
service.Url = new Uri(Service_URL);
for (int I = 0; I < iCounter; ++I)
{
try
{
string myGUID = "{" + dt.Rows[I]["GUID"].ToString() + "}";
if (IsValidEmailAddress(dt.Rows[I]["OwnerEmail"].ToString()) == false)
{
DeliveryReportDAL myReport = new DeliveryReportDAL();
myReport.SaveSentStatus(myGUID, 'G', 3);
continue;
}
EmailMessage message = new EmailMessage(service);
message.Subject = dt.Rows[I]["TemplateSubject"].ToString();
message.Body = dt.Rows[I]["TemplateText"].ToString().Replace("\0", " ");
message.ToRecipients.Add(dt.Rows[I]["OwnerEmail"].ToString());
message.IsDeliveryReceiptRequested = true;
Guid myPropertySetId = new Guid(myGUID);
ExtendedPropertyDefinition myExtendedPropertyDefinition = new ExtendedPropertyDefinition(myPropertySetId, "blablabla", MapiPropertyType.String);
ServicePointManager.ServerCertificateValidationCallback =
delegate(object sender1,
System.Security.Cryptography.X509Certificates.X509Certificate certificate,
System.Security.Cryptography.X509Certificates.X509Chain chain,
System.Net.Security.SslPolicyErrors sslPolicyErrors)
{ return true; };
message.SendAndSaveCopy();
DeliveryReportDAL myReport1 = new DeliveryReportDAL();
myReport1.SaveSentStatus(dt.Rows[I]["GUID"].ToString(), 'G', 1);
}
catch (Exception ex)
{
new Util().LogError(ex, "SMTP:: SendBulkMarketing 2nd catch");
}
}
}
return iCounter;
}
I would greatly appreciate any help in improving the performance of my code.

This performance issue is now resolved.
It was a fundamental coding problem. The issue was caused by a separate method call which was being called (not shown in the code snippet provided) inside the for loop. It contains performance heavy functionality, but it did not need to be called inside the for loop.
Moving this performance heavy method call outside of the for loop resolved the issue.

Related

How to fix 'The the message received was unexpected or badly formatted'

I've been trying to fix this problem for a while now, but everything I've tried is useless. I tried HttpClientHandler but still getting the error!
Error messages:
SSL connection could not be established, see inner exception
Authentication failed, see inner exception
The the message received was unexpected or badly formatted
[Command("stats")]
public async Task Profileosu([Remainder]string username = null)
{
try
{
clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };
HttpClient client = new HttpClient(clientHandler,disposeHandler: true);
List<Player> player = new List<Player>();
List<string> lines = File.ReadAllLines(path, encoding: Encoding.UTF8).ToList();
string id = "";
foreach (var line in lines)
{
string[] readed = line.Split(",");
Player newPlayer = new Player();
newPlayer.id = readed[0];
newPlayer.osuname = readed[1];
player.Add(newPlayer);
}
if (username is null)
{
id = Context.User.Id.ToString();
username = Context.User.Username;
}
else if (Context.Message.MentionedUsers.Count > 0)
{
username = Context.Message.MentionedUsers.First().Username;
id = Context.Message.MentionedUsers.First().Id.ToString();
}
for (int i = 0; i < player.Count(); i++)
{
if (player[i].id == id)
{
username = player[i].osuname;
}
}
string url = $"https://osu.ppy.sh/api/get_user?k={k}&u={username}";
string osuProf = await client.GetStringAsync(url);
dynamic osuProfile = JsonConvert.DeserializeObject<dynamic>(value: osuProf);
string pp_raw = osuProfile[0]["pp_raw"];
string country = osuProfile[0]["country"];
string user_id = osuProfile[0]["user_id"];
string joinDate = osuProfile[0]["join_date"];
string rank = osuProfile[0]["pp_rank"];
string countryRank = osuProfile[0]["pp_country_rank"];
string accuracy = osuProfile[0]["accuracy"];
string playcount = osuProfile[0]["playcount"];
string userName = osuProfile[0]["username"];
embed.WithThumbnailUrl($"https://a.ppy.sh/{user_id}");
embed.WithAuthor($"{username} #{rank}, {pp_raw}PP", Context.Guild.CurrentUser.GetAvatarUrl(), $"https://osu.ppy.sh/users/{user_id}");
embed.WithDescription($"Join date:{joinDate}\nCountry:{country} #{countryRank}\n");
embed.WithFooter($"Accuray:{double.Parse(accuracy):F2}%\t\tPlaycount:{playcount}");
embed.WithColor(154, 255, 0);
await ReplyAsync($"", false, embed.Build());
}
catch (Exception ex)
{
embed.WithAuthor("An error occurred");
embed.WithDescription("This player doesn't exist! Please check the username and try again!");
embed.WithColor(255, 0, 0);
await ReplyAsync($"", false, embed.Build());
Console.WriteLine(ex.Message);
if (ex.InnerException != null)
{
Console.WriteLine(ex.InnerException.Message);
}
if (ex.InnerException.InnerException.Message != null)
{
Console.WriteLine(ex.InnerException.InnerException.Message);
}
}
}
I learning c# from scratch and I am very beginner in the language so please explain what's the problem.
This is most likely happening due to the clientHandler you define and use.
For communication with the OSU API you would not really need this either.
So instead, you could go ahead and let the HttpClient handle this for you.
So instead of:
clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };
HttpClient client = new HttpClient(clientHandler,disposeHandler: true);
You can define the HttpClient as follows:
HttpClient client = new HttpClient();
As you now no longer define the disposeHandler, it would be a good practice to either add a Finally to your try catch.
Or by applying a using to the HttpClient.
using (var client = new HttpClient())
{
string url = $"https://osu.ppy.sh/api/get_user?k={Key}&u=d3ullist";
string osuProf = await client.GetStringAsync(url);
dynamic osuProfile = JsonConvert.DeserializeObject<dynamic>(value: osuProf);
}
Which will end up with the dynamic object as you where previously expecting it.

"RPC Server is unavailable" when exporting Outlook contacts to CSV

I am exporting Outlook contacts with a custom form to CSV from a specific Contacts folder. This folder is not the default location. It is a large folder with almost 7,000 contacts. This is a shared mailbox in Office 365, but we can't use the Outlook or Graph APIs because of the custom data.
My code below works fine, except that after iterating through 200-800 contacts, I get this error: "RPC Server is unavailable. (Exception from HRESULT: 0x800706BA)."
I also tried exporting the folder to a .pst and accessing that folder on my local machine. The result is essentially the same. UPDATE: I've been watching Outlook.exe in the task manager, and it steadily increases its memory consumption to around 300MB before crashing. I've tried the same code on a laptop running Office 2010, and I get an "Out of Memory" error.
I get the error whether Outlook is open or closed, but closing Outlook during program operation will immediately trigger this error. Outlook either starts (or restarts) following this error. I've read a number of SO posts and articles related to this error, but I'm not sure exactly what's going on. Any help is appreciated.
UPDATE: Code has been updated to use for loops instead of foreach loops per Dmitry Streblechenko's suggestion.
using System;
using Microsoft.Office.Interop.Outlook;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
namespace OutlookContacts
{
class Program
{
static void Main(string[] args)
{
var encoding = Encoding.UTF8;
string csvPath = #"myCSVPath";
Application outlook = new Application();
NameSpace ns = outlook.GetNamespace("MAPI");
MAPIFolder sharedContacts;
string recipientName = "myEmail#myDomain";
StringBuilder headerRow = new StringBuilder();
Recipient recip = ns.CreateRecipient(recipientName);
StreamWriter writer = new StreamWriter(csvPath, false, encoding);
recip.Resolve();
if (recip.Resolved)
{
try
{
//EntryID and StoreID of my folder
sharedContacts =
ns.GetFolderFromID(
"myEntryID",
"myStoreID"
);
Items contacts = sharedContacts.Items;
//Writing header row
ContactItem first = contacts.GetFirst();
var properties = first.ItemProperties;
for(int i = 0; i < properties.Count; i++)
{
try
{
headerRow.Append(string.Format("\"{0}\",", properties[i].Name));
}
catch (System.Exception ex)
{
headerRow.Append(string.Format("{0},", ex.Message));
}
}
headerRow.AppendLine(Environment.NewLine);
WriteToCSV(writer, headerRow);
Console.WriteLine("Header row written;");
Marshal.ReleaseComObject(properties);
Marshal.ReleaseComObject(first);
//Writing Records
for (int i = 1; i <= contacts.Count; i++)
{
object o = contacts[i];
if (o is ContactItem)
{
ContactItem contact = (ContactItem)o;
if (contact != null)
{
Console.Write(contact.FullName);
StringBuilder dataRow = new StringBuilder();
ItemProperties contactProps = contact.ItemProperties;
for (int j = 0; j < contactProps.Count; j++)
{
ItemProperty property = contactProps[j];
try
{
if (property.Value == null)
{
string value = "null,";
dataRow.Append(value);
}
//else if (property.Name == "Attachments")
//{
// //Attachment file names
// string attachment = "";
// for (int k = 1; k < contact.Attachments.Count; k++)
// {
// attachment = (string.Format("\"{0}\"; ", contact.Attachments[k].FileName));
// dataRow.Append(attachment);
// }
// dataRow.Append(",");
//}
else
{
string value = property.Value.ToString();
value = value.Replace("\r\n\r\n\r\n", "\r\n")
.Replace("\r\n\r\n", "\r\n")
.Replace("\"", "'");
value = (string.Format("\"{0}\",", value));
dataRow.Append(value);
}
}
catch (System.Exception ex)
{
string value = string.Format("{0}: {1},", property.Name, ex.Message);
dataRow.Append(value);
}
Marshal.ReleaseComObject(property);
}
dataRow.Append(Environment.NewLine);
WriteToCSV(writer, dataRow);
Marshal.ReleaseComObject(contactProps);
Marshal.ReleaseComObject(contact);
}
Marshal.ReleaseComObject(o);
counter++;
Console.WriteLine(": Written " + counter);
}
}
}
catch (System.Exception ex)
{
Console.WriteLine(dataRow.ToString(), ex.Message);
Console.ReadKey();
}
}
}
static void WriteToCSV(StreamWriter writer, StringBuilder row)
{
var data = row.ToString();
writer.WriteAsync(data);
}
}
}
Looks like you are running out of RPC channels. You need to avoid using foreach loops (they tend to keep all collection members referenced until the loop exits) and explicitly release all COM objects are soon as you are done with them.
Off the top of my head:
for(int i = 1; i <= contacts.Count; i++)
{
obejct o = contacts[i];
ContactItem contact = o as ContactItem;
if (o != null)
{
ItemProperties properties = contact.ItemProperties;
StringBuilder newLine = new StringBuilder();
for (int j = 1; j <= properties.Count; j++)
{
ItemProperty property = properties[j];
var value = "";
if (property.Value == null)
{
value = "null,";
Console.WriteLine(value);
newLine.Append(value);
}
else
{
value = property.Value.ToString() + ",";
newLine.Append(value);
}
Marshal.ReleaseComObject(property);
}
newLine.Append(Environment.NewLine);
WriteToCSV(writer, newLine);
Marshal.ReleaseComObject(properties);
Marshal.ReleaseComObject(contact);
}
Marshal.ReleaseComObject(o);
}

Web application Task Parallel threads

I wrote a simple application that sends out bulk emails. It uses a parallel foreach loop to send emails via system.net.mail. The parallel foreach loop is surrounded by a for loop which was chunking up a 15000 email list into 20 each and waiting 1 second by a thread.sleep. I set the executiontimeout to 7200 in the web config. This application should have been done within an hour easy. My question is - why did the application take over a hour to complete. Is it waiting for the threads to complete or something? How can I make it stop? It eventually timed out through another timer - but??? I am new to threading - I am having a hard time trying to wrap my head around this one.
var chunk = emailList.Select((value, index) => new { Index = index, Value = value })
.GroupBy(x => x.Index / Convert.ToInt32(chunkSize))
.Select(g => g.Select(x => x.Value).ToList())
.ToList();
for (int i = 0; i < chunk.Count; i++)
{
if (i > 0)
{
if (!String.IsNullOrEmpty(waitTime))
{
//mre.WaitOne(Convert.ToInt32(waitTime));
//mre.Reset();
Thread.Sleep(Convert.ToInt32(waitTime));
}
}
Parallel.ForEach(chunk[i], email =>
{
try
{
MailMessage em = new MailMessage();
em.From = new MailAddress(tbEmailFrom.Text);
em.To.Add(email.ToString().Trim());
if (!String.IsNullOrEmpty(tbEmailCC.Text))
{
em.CC.Add(tbEmailCC.Text);
}
if (!String.IsNullOrEmpty(tbEmailBC.Text))
{
em.Bcc.Add(tbEmailBC.Text);
}
em.ReplyToList.Add(tbReplyTo.Text);
em.Body = tbEmailBody.Text;
em.IsBodyHtml = true;
em.Subject = tbSubject.Text;
em.Priority = System.Net.Mail.MailPriority.Normal;
em.BodyEncoding = System.Text.Encoding.UTF8;
using (SmtpClient sm = new SmtpClient())
{
if (String.IsNullOrEmpty(smtpServer))
{
sm.Host = Host.SMTPServer;
}
else
{
sm.UseDefaultCredentials = false;
sm.Host = smtpServer;
sm.Credentials = new System.Net.NetworkCredential(smtpUsername, smtpPassword);
}
sm.Send(em);
}
Interlocked.Increment(ref count);
}
catch (SmtpException smtp)
{
errorList.Add(email.ToString() + "<br />");
}
catch (Exception ex)
{
errorList.Add(email.ToString() + "<br />");
Exceptions.LogException(ex);
}
});
}

Bloomberg web service call for single field and single instrument taking more than 1 min

I am making a Bloomberg web service GetData call for the "DEBT_TO_EQUITY_FUNDAMENTALS_TKR" field. I am setting secmaster = true and asking for a single instrument with a CUSIP identifier (with yellowkey = MarketSector.Corp).
This strikes me as a fairly lightweight call having seen people asking for thousands of instruments and dozens of fields at once.
I have played around with setting lots of different settings but I just can't get this request to return in a few seconds. It gives me the correct return value but it takes longer than 60 seconds.
Any idea if it is possible to get such a request to execute and return in a few seconds?
Thanks
EDIT - Here is the code I am running:
public string GetFundamentalTicker(string identifier, InstrumentType identifierType = InstrumentType.CUSIP)
{
PerSecurityWS ps = new PerSecurityWS();
try
{
log.DebugFormat("Cert path is: {0}", CertPath);
X509Certificate2 clientCert = new X509Certificate2(CertPath, "<password_redacted>");
ps.ClientCertificates.Add(clientCert);
}
catch (Exception e)
{
log.ErrorFormat("Error in cert setup - {0} - {1}", e.Message, e.InnerException == null ? "" : e.InnerException.Message);
return null;
}
//Set request header
GetDataHeaders getDataHeaders = new GetDataHeaders();
getDataHeaders.secmaster = true;
getDataHeaders.secmasterSpecified = true;
//getDataHeaders.fundamentals = true;
//getDataHeaders.fundamentalsSpecified = true;
//getDataHeaders.programflag = ProgramFlag.oneshot;//unnecessary - defaults to this anyway
//getDataHeaders.programflagSpecified = true;
//getDataHeaders.pricing = true;
getDataHeaders.secid = identifierType;
getDataHeaders.secidSpecified = true;
SubmitGetDataRequest sbmtGtDtreq = new SubmitGetDataRequest();
sbmtGtDtreq.headers = getDataHeaders;
sbmtGtDtreq.fields = new string[] {
"DEBT_TO_EQUITY_FUNDAMENTALS_TKR"
};
int currentFundYear = DateTime.Now.Year;
//var fundYears = new List<int>();
List<Instrument> fundYearInstruments = new List<Instrument>();
Instrument fundYearInstrument = null;
fundYearInstrument = new Instrument();
fundYearInstrument.id = identifier;
fundYearInstrument.typeSpecified = true;
fundYearInstrument.type = identifierType;
fundYearInstrument.yellowkey = MarketSector.Corp;
fundYearInstrument.yellowkeySpecified = true;
//fundYearInstrument.overrides = new Override[] {};//{ new Override() { field = "EQY_FUND_YEAR", value = currentFundYear.ToString() } };
fundYearInstruments.Add(fundYearInstrument);
//fundYears.Add(-1);
Instrument[] instr = fundYearInstruments.ToArray();
Instruments instrs = new Instruments();
instrs.instrument = instr;
sbmtGtDtreq.instruments = instrs;
try
{
SubmitGetDataResponse sbmtGtDtResp = ps.submitGetDataRequest(sbmtGtDtreq);
RetrieveGetDataRequest rtrvGtDrReq = new RetrieveGetDataRequest();
rtrvGtDrReq.responseId = sbmtGtDtResp.responseId;
RetrieveGetDataResponse rtrvGtDrResp;
do
{
System.Threading.Thread.Sleep(POLL_INTERVAL);
rtrvGtDrResp = ps.retrieveGetDataResponse(rtrvGtDrReq);
}
while (rtrvGtDrResp.statusCode.code == DATA_NOT_AVAILABLE);
if (rtrvGtDrResp.statusCode.code == SUCCESS)
{
for (int i = 0; i < rtrvGtDrResp.instrumentDatas.Length; i++)
{
for (int j = 0; j < rtrvGtDrResp.instrumentDatas[i].data.Length; j++)
{
if (rtrvGtDrResp.instrumentDatas[i].data[j].value == "N.A." || rtrvGtDrResp.instrumentDatas[i].data[j].value == "N.S." || rtrvGtDrResp.instrumentDatas[i].data[j].value == "N.D.")
rtrvGtDrResp.instrumentDatas[i].data[j].value = null;
return rtrvGtDrResp.instrumentDatas[i].data[j].value;
}
}
return null;
}
else if (rtrvGtDrResp.statusCode.code == REQUEST_ERROR)
{
log.ErrorFormat("Error in the submitted request: {0}", rtrvGtDrResp.statusCode.description);
return null;
}
}
catch (Exception e)
{
log.ErrorFormat("Error in GetData - {0} - {1}", e.Message, e.InnerException == null ? "" : e.InnerException.Message);
return null;
}
return null;
}
Poll interval is 5 seconds and the SOAP web service url is:
https://software.bloomberg.com/datalicensewp/dlws.wsdl
I am having the same issue. I found out that there is a difference between making the same call to Bloomberg API from, for example, console app (works very fast) and web service (takes a lot of time to start session). And the difference is that console app runs under the same user as bbcomm process, whereas web service (or actually iis process) runs under System account. You can try to log out all users on the PC where web service is hosted and then try to make the call. In this case, I guess, bbcomm goes under System account as no one else is logged in and works fast. It worked for me and the call was answered instantly.

Execute mail reader program without visual studio

With reference to my previous question, I already wrote my program and it is working awesome when I am using VS2008 for run it.
I have two more questions:
1. I want to check with you guys when I run my program all the mail are appearing in VS output as xml file, but I never used to print them in output. is it usual for all or I need to add something to remove it. I feel it takes long time from my PC to show mails in output.
2. my second question is that when I want to use only exe file stand alone(run program via exe file not with VS ) I am receiving below error and program is hanging & close.
"MailReader has encountered a problem and needs to close. We are
sorry for the inconvenience."
As I mentioned above this program is working fine in VS.
I copy part of my code that read mails and split them for your reference.
public void ReadMail()
{
ServicePointManager.ServerCertificateValidationCallback += delegate(object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors) { return true; };
try
{
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
service.TraceEnabled = true;
service.Credentials = new WebCredentials(_username, _password); //Modify this
service.Url = new Uri(_exchange); //Modify this
service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
service.Url = new Uri(_exchange);
service.TraceEnabled = true;
service.Credentials = new WebCredentials(_username, _password); //Modify this
service.Url = new Uri(_exchange);
//SearchFilter to get unreaded messages only.
SearchFilter sf = new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false));
ItemView itemview = new ItemView(Int16.MaxValue);
//DateTime searchdate = new DateTime(2012, 7, 6); //Year, month, day
SearchFilter greaterthanfilter = new SearchFilter.IsGreaterThan(ItemSchema.DateTimeSent, Convert.ToDateTime(startDate));
SearchFilter lessthanfilter = new SearchFilter.IsLessThan(ItemSchema.DateTimeSent,Convert.ToDateTime(finishDate));
SearchFilter[] f = { greaterthanfilter, lessthanfilter };
SearchFilter filter = new SearchFilter.SearchFilterCollection(LogicalOperator.And, f);
//Folder folder = Folder.Bind(this.m_Service, WellKnownFolderName.MsgFolderRoot); //Or the folder you want to search in
//FindItemsResults<Item> results = folder.FindItems(filter, new ItemView(1000));
FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.SentItems,filter, itemview);
Action action = () => fr.setText(findResults.Items.Count + "mails need to analysis from "+startDate +" to "+ finishDate);
fr.Invoke(action, null);
action = () => fr.setMaximumProgressBar(findResults.Items.Count);
fr.Invoke(action, null);
dmd = new List<DailyMailDetails>();
foreach (Item item in findResults.Items)
{
string messageDate = "Error in Date";
string messageSubj = "Error in Subject";
int index = 0;
try
{
PropertySet propertySet = new PropertySet(BasePropertySet.FirstClassProperties, ItemSchema.DateTimeSent, ItemSchema.Body, ItemSchema.Subject);
propertySet.RequestedBodyType = BodyType.Text;
EmailMessage message = EmailMessage.Bind(service, item.Id, propertySet);
string temp = startSign.ToUpper();
int start = message.Body.Text.ToUpper().IndexOf(temp) + temp.Length;
int end = message.Body.Text.ToUpper().IndexOf(finishSign.ToUpper());
int len = end - start;
string text = message.Body.Text.Substring(start, len);
index = findDmdIndex(message.DateTimeSent.ToShortDateString().ToString());
if (index == -1)
{
dmd.Add(new DailyMailDetails(message.DateTimeSent.ToShortDateString().ToString(), (List<PeopleSigniture>)Extensions.Clone<PeopleSigniture>(OrginallistPeopleSign)));
index = dmd.Count - 1;
}
bool signExist = false;
for (int i = 0; i < listPeopleSign.Count; i++)
if (text.ToUpper().Contains(dmd[index].peopleSign[i].Signiture.ToUpper()))
{
dmd[index].peopleSign[i].addResponse(message.DateTimeSent.ToString(), message.Subject.ToString());
signExist = true;
break;
}
messageDate = message.DateTimeSent.ToString();
messageSubj = message.Subject.ToString();
if (!signExist)
dmd[index].peopleSign[dmd[index].peopleSign.Count - 2].addResponse(message.DateTimeSent.ToString(), message.Subject.ToString());
}
catch (Exception ex)
{
dmd[index].peopleSign[dmd[index].peopleSign.Count - 1].addResponse(messageDate, messageSubj);
}
action = () => fr.increasePrograss();
fr.Invoke(action, null);
}
}
catch (Exception ex)
{
MessageBox.Show("Class: Mail Function:ReadMail" + ex.Message);
}
Action action2 = () => fr.setText(ToString(true),dmd);
fr.Invoke(action2, null);
}
For issue #1 - you are viewing the XML output likely because you have EWS tracing enabled. You need to set ExchangeService.TraceEnabled to false or comment it out entirely. (You also have many duplicate lines of code you need to cleanup.)
service.TraceEnabled = false;
For issue #2 - you need to determine the actual .NET exception. Without this - we cannot help you further. It could be crashing for countless reasons. Please provide a stack trace.

Categories

Resources