473,327 Members | 2,007 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,327 software developers and data experts.

threading

I have two loops that I am running, one of which is calling a method
which contains the second one. What I want to happen is for when the
second loop exits (the inner loop), then the code will return to the
first loop (the outer loop) and continue executing, but this doesn't
seem to be happening. Here is my code if anybody can help me out :

Loop 1 :

for (int i = 0; i < oItems.Count; i++)
{
oItems = oInbox.Items;

ProgressWindow progress = new ProgressWindow();
progress.Text = "Work";
System.Threading.ThreadPool.QueueUserWorkItem(new
System.Threading.WaitCallback(MoveMail), new object[] { progress,
oItems, destfolder, objConn });

if (oItems.Count == 1)
{
i = -1;
}
else
{
i = 0;
}

progress.ShowDialog();
}

Loop 2 in MoveMail method :

private void MoveMail(object status)
{
object[] parms = (object[])status;
IProgressCallback callback = (IProgressCallback)parms[0];
Outlook.Items col = (Outlook.Items)parms[1];
Outlook.MAPIFolder destfolder =
(Outlook.MAPIFolder)parms[2];
SqlConnection objConn = (SqlConnection)parms[3];

string strInsertQuery = "";

callback.Begin(0, col.Count);

for (int i = 1; i < col.Count + 1; i++)
{
callback.SetText(String.Format("Performing op: {0}",
i));
callback.StepTo(i);

if (callback.IsAborting)
{
return;
}

if (col.Item(i) is Outlook.MailItem)
{
Outlook.MailItem oMsg =
(Outlook.MailItem)col.Item(i);

//subject
if ((oMsg.Subject == null) || (oMsg.Subject == ""))
{
oMsg.Subject = "blank";
}
else
{
//escape quotes in subject
oMsg.Subject = oMsg.Subject.Replace("'", "''");
}

if (oMsg.ReceivedByName == null)
{
if (oMsg.SenderName.IndexOf("'") != -1)
{
string strSenderName =
oMsg.SenderName.Replace("'", "''");

strInsertQuery = "INSERT INTO SeedingResults
(SenderName, ReceivedTime, Subject) VALUES ('" + strSenderName + "','" +
oMsg.ReceivedTime.ToString() + "','" + oMsg.Subject.ToString() + "')";
}
else
{
strInsertQuery = "INSERT INTO SeedingResults
(SenderName, ReceivedTime, Subject) VALUES ('" +
oMsg.SenderName.ToString() + "','" + oMsg.ReceivedTime.ToString() +
"','" + oMsg.Subject.ToString() + "')";
}
}
else
{
if (oMsg.SenderName.IndexOf("'") != -1)
{
string strSenderName2 =
oMsg.SenderName.Replace("'", "''");

strInsertQuery = "INSERT INTO SeedingResults
(ReceivedByName, SenderName, ReceivedTime, Subject) VALUES ('" +
oMsg.ReceivedByName.ToString() + "','" + strSenderName2 + "','" +
oMsg.ReceivedTime.ToString() + "','" + oMsg.Subject.ToString() + "')";
}
else
{
strInsertQuery = "INSERT INTO SeedingResults
(ReceivedByName, SenderName, ReceivedTime, Subject) VALUES ('" +
oMsg.ReceivedByName.ToString() + "','" + oMsg.SenderName.ToString() +
"','" + oMsg.ReceivedTime.ToString() + "','" + oMsg.Subject.ToString() +
"')";
}
}

//write to database
SqlCommand objInsertCommand = new
SqlCommand(strInsertQuery, objConn);

try
{
objInsertCommand.ExecuteNonQuery();
}
catch
{
throw new DatabaseException();
}

oMsg.Move(destfolder);

if (callback.IsAborting)
{
return;
}
}
}
}

*** Sent via Developersdex http://www.developersdex.com ***
Mar 20 '07 #1
10 3659
On Mar 20, 12:40 pm, Mike P <mike.p...@gmail.comwrote:
I have two loops that I am running, one of which is calling a method
which contains the second one. What I want to happen is for when the
second loop exits (the inner loop), then the code will return to the
first loop (the outer loop) and continue executing, but this doesn't
seem to be happening. Here is my code if anybody can help me out :
There's a lot of code there, most of it not relevant to the problem.

Could you post a short but complete program that demonstrates the
problem?
See http://pobox.com/~skeet/csharp/complete/html for more on what I
mean by this.

Jon

Mar 20 '07 #2
Here's the code cut down :

Loop 1 :

for (int i = 0; i < oItems.Count; i++)
{
oItems = oInbox.Items;

ProgressWindow progress = new ProgressWindow();
progress.Text = "Work";
System.Threading.ThreadPool.QueueUserWorkItem(new
System.Threading.WaitCallback(MoveMail), new object[] { progress,
oItems, destfolder, objConn });

if (oItems.Count == 1)
{
i = -1;
}
else
{
i = 0;
}

progress.ShowDialog();
}

Loop 2 :

private void MoveMail(object status)
{
object[] parms = (object[])status;
IProgressCallback callback = (IProgressCallback)parms[0];
Outlook.Items col = (Outlook.Items)parms[1];
Outlook.MAPIFolder destfolder =
(Outlook.MAPIFolder)parms[2];
SqlConnection objConn = (SqlConnection)parms[3];

string strInsertQuery = "";

callback.Begin(0, col.Count);

for (int i = 1; i < col.Count + 1; i++)
{
callback.SetText(String.Format("Performing op: {0}",
i));
callback.StepTo(i);

if (callback.IsAborting)
{
return;
}

if (col.Item(i) is Outlook.MailItem)
{
Outlook.MailItem oMsg =
(Outlook.MailItem)col.Item(i);

//db stuff goes here

oMsg.Move(destfolder);

if (callback.IsAborting)
{
return;
}
}
}
}
*** Sent via Developersdex http://www.developersdex.com ***
Mar 20 '07 #3
On Mar 20, 2:00 pm, Mike P <mike.p...@gmail.comwrote:
Here's the code cut down :
<snip>

Please read http://www.yoda.arachsys.com/csharp/incomplete.html

Jon

Mar 20 '07 #4
Here's another attempt :

Main form :

Outlook.Application oApp = new Outlook.ApplicationClass();

Outlook.NameSpace oNS = oApp.GetNamespace("mapi");

string strUserName =
System.Environment.UserName.ToString();

oNS.Logon(strUserName, System.Reflection.Missing.Value, false, true);

Outlook.MAPIFolder oInbox =
oNS.GetDefaultFolder(Outlook.OlDefaultFolders.olFo lderInbox);

Outlook.MAPIFolder destfolder =
oInbox.Folders.Item("Archive");

Outlook.Items oItems = oInbox.Items;

int intTotalNumberOfItemsInInbox = oItems.Count;

for (int i = 0; i < oItems.Count; i++)
{
oItems = oInbox.Items;

ProgressWindow progress = new ProgressWindow();
progress.Text = "Work";
System.Threading.ThreadPool.QueueUserWorkItem(new
System.Threading.WaitCallback(MoveMail), new object[] { progress,
oItems, destfolder, objConn });

if (oItems.Count == 1)
{
i = -1;
}
else
{
i = 0;
}

progress.ShowDialog();
}

private void MoveMail(object status)
{
object[] parms = (object[])status;
IProgressCallback callback = (IProgressCallback)parms[0];
Outlook.Items col = (Outlook.Items)parms[1];
Outlook.MAPIFolder destfolder =
(Outlook.MAPIFolder)parms[2];
SqlConnection objConn = (SqlConnection)parms[3];

callback.Begin(0, col.Count);

for (int i = 1; i < col.Count + 1; i++)
{
callback.SetText(String.Format("Performing op: {0}",
i));
callback.StepTo(i);

if (callback.IsAborting)
{
return;
}

if (col.Item(i) is Outlook.MailItem)
{
Outlook.MailItem oMsg =
(Outlook.MailItem)col.Item(i);

oMsg.Move(destfolder);

if (callback.IsAborting)
{
return;
}
}
}
}

Added to this I am using ProgressWindow.cs and IProgressCallback.cs from
the following example :

http://www.codeproject.com/cs/miscct...ressdialog.asp

HTH,

Mike


*** Sent via Developersdex http://www.developersdex.com ***
Mar 20 '07 #5
The problem I have with this code is that without the threading code,
after it has completed executing inside the second loop it returns to
the first loop, whereas when the threading code is added, it doesn't.
Here's the code in it's original form :

for (int i = 0; i < oItems.Count; i++)
{
oItems = oInbox.Items;

MoveMail(oItems, destfolder, objConn);

if (oItems.Count == 1)
{
i = -1;
}
else
{
i = 0;
}

private void MoveMail(Outlook.Items col, Outlook.MAPIFolder destfolder,
SqlConnection objConn)
{

for (int i = 1; i < col.Count + 1; i++)
{
if (col.Item(i) is Outlook.MailItem)
{
Outlook.MailItem oMsg =
(Outlook.MailItem)col.Item(i);

oMsg.Move(destfolder);
}
}
}

*** Sent via Developersdex http://www.developersdex.com ***
Mar 20 '07 #6
On Mar 20, 2:23 pm, Mike P <mike.p...@gmail.comwrote:
Here's another attempt :
*Please* read the link I gave.

Try to cut and paste the code you've posted directly into an empty
file and compile it. It won't work, because it's incomplete.

Also, anything which requires Outlook isn't going to be easy for
everyone to reproduce. Put in some dummy work (eg writing a counter to
the console). This isn't meant to be real code, it's meant to be code
which *just* demonstrates the problem.

Jon

Mar 20 '07 #7
"Mike P" <mi*******@gmail.comwrote in message
news:ue**************@TK2MSFTNGP05.phx.gbl...
Here's another attempt :

Main form :

Outlook.Application oApp = new Outlook.ApplicationClass();

Outlook.NameSpace oNS = oApp.GetNamespace("mapi");

string strUserName =
System.Environment.UserName.ToString();

oNS.Logon(strUserName, System.Reflection.Missing.Value, false, true);

Outlook.MAPIFolder oInbox =
oNS.GetDefaultFolder(Outlook.OlDefaultFolders.olFo lderInbox);

Outlook.MAPIFolder destfolder =
oInbox.Folders.Item("Archive");

Outlook.Items oItems = oInbox.Items;

int intTotalNumberOfItemsInInbox = oItems.Count;

for (int i = 0; i < oItems.Count; i++)
{
oItems = oInbox.Items;

ProgressWindow progress = new ProgressWindow();
progress.Text = "Work";
System.Threading.ThreadPool.QueueUserWorkItem(new
System.Threading.WaitCallback(MoveMail), new object[] { progress,
oItems, destfolder, objConn });

if (oItems.Count == 1)
{
i = -1;
}
else
{
i = 0;
}

progress.ShowDialog();
}

private void MoveMail(object status)
{
object[] parms = (object[])status;
IProgressCallback callback = (IProgressCallback)parms[0];
Outlook.Items col = (Outlook.Items)parms[1];
Outlook.MAPIFolder destfolder =
(Outlook.MAPIFolder)parms[2];
SqlConnection objConn = (SqlConnection)parms[3];

callback.Begin(0, col.Count);

for (int i = 1; i < col.Count + 1; i++)
{
callback.SetText(String.Format("Performing op: {0}",
i));
callback.StepTo(i);

if (callback.IsAborting)
{
return;
}

if (col.Item(i) is Outlook.MailItem)
{
Outlook.MailItem oMsg =
(Outlook.MailItem)col.Item(i);

oMsg.Move(destfolder);

if (callback.IsAborting)
{
return;
}
}
}
}

Added to this I am using ProgressWindow.cs and IProgressCallback.cs from
the following example :

http://www.codeproject.com/cs/miscct...ressdialog.asp

HTH,

Mike


*** Sent via Developersdex http://www.developersdex.com ***


It's really hard to see what's going on, but I would suggest you to forget about a
threadpool thread, use a 'normal auxiliary' thread and initialize this one to enter the STA.
This way you are creating the COM reference on the main UI thread (STA) and you pass COM
references to a worker thread taken from the pool, however these pool threads are running in
the MTA, that means that you probably have to deal with marshaling issues between the MTA
and the STA thread.
Another option is to create the "Outlook" instance from the auxiliary thread, don't
initialize it to enter an STA, should work from MTA.

Willy.


Mar 20 '07 #8
Willy,

Apologies, I'm new to threading, but what do you mean by MTA?
Thanks,

Mike
*** Sent via Developersdex http://www.developersdex.com ***
Mar 21 '07 #9
Willy,

Apologies, I'm new to threading, but what do you mean by MTA?
Thanks,

Mike
*** Sent via Developersdex http://www.developersdex.com ***
Mar 21 '07 #10
"Mike P" <mi*******@gmail.comwrote in message
news:uQ**************@TK2MSFTNGP06.phx.gbl...
Willy,

Apologies, I'm new to threading, but what do you mean by MTA?
Thanks,

Mike
*** Sent via Developersdex http://www.developersdex.com ***

STA and MTA are COM acronyms that stand for Single Threaded Apartment and Multi Threaded
Apartment respectively. Apartments define synchronization context boundaries and are mainly
used by COM clients to help them to solve synchronization issues when calling across these
boundaries.
All Windows Forms (and WPF) applications are tied to the COM Threading Model, that is, a UI
thread needs to enter a STA to function properly. And each call into COM must be done from a
COM initialized thread, that is, each such thread must have joined the MTA (one per process)
or must have initialized the thread to enter a STA (max. one per thread).

There is a lot of COM information available in MSDN, you shouldn't read all of it ;-), start
slowly, but at least try to get some basic knowledge about this technology.

Here is something that should give you a head start :
http://blogs.msdn.com/larryosterman/...28/122240.aspx

Msdn contains more detailed information...
http://msdn2.microsoft.com/en-us/library/ms680112.aspx
http://msdn2.microsoft.com/en-us/library/ms693421.aspx

Just as there are some good articles available on codeproject:

http://www.codeproject.com/com/CCOMThread.asp
http://www.codeproject.com/com/CCOMThread2.asp
WIlly.

Mar 21 '07 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

65
by: Anthony_Barker | last post by:
I have been reading a book about the evolution of the Basic programming language. The author states that Basic - particularly Microsoft's version is full of compromises which crept in along the...
2
by: Egor Bolonev | last post by:
hi all my program terminates with error i dont know why it tells 'TypeError: run() takes exactly 1 argument (10 given)' =program==================== import os, os.path, threading, sys def...
77
by: Jon Skeet [C# MVP] | last post by:
Please excuse the cross-post - I'm pretty sure I've had interest in the article on all the groups this is posted to. I've finally managed to finish my article on multi-threading - at least for...
6
by: CK | last post by:
I have the following code in a windows service, when I start the windows service process1 and process2 work fine , but final process (3) doesnt get called. i stop and restart the windows service...
2
by: Vjay77 | last post by:
In this code: Private Sub downloadBtn_Click(ByVal sender As Object, ByVal e As System.EventArgs) If Not (Me.downloadUrlTextBox.Text = "") Then Me.outputGroupBox.Enabled = True...
11
by: Paul Sijben | last post by:
I am stumped by the following problem. I have a large multi-threaded server accepting communications on one UDP port (chosen for its supposed speed). I have been profiling the code and found...
17
by: OlafMeding | last post by:
Below are 2 files that isolate the problem. Note, both programs hang (stop responding) with hyper-threading turned on (a BIOS setting), but work as expected with hyper-threading turned off. ...
0
by: kingcrowbar.list | last post by:
Hello Everyone I have been playing a little with pyGTK and threading to come up with simple alert dialog which plays a sound in the background. The need for threading came when in the first...
7
by: Mike P | last post by:
I am trying to write my first program using threading..basically I am moving messages from an Outlook inbox and want to show the user where the process is up to without having to wait until it has...
126
by: Dann Corbit | last post by:
Rather than create a new way of doing things: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2497.html why not just pick up ACE into the existing standard:...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.