2

The 'login failed' error has never resurfaced, curious? However the other connection errors seem to be explained by slamming the server. The randomness with which the errors occur, still a mystery.

Login failed. The login is from an untrusted domain and cannot be used with Windows authentication

I wanted to get my code running in parallel, so I changed my foreach loop to a parallel foreach loop. It seemed simple enough. Each loop connects to the database, looks up some stuff, performs some logic, adds some stuff, closes the connection. But I get the above error?

I'm using my local sql server and entity framework (each loop uses it's own context). Is there some problem with connecting multiple times using the same local login or something? How did I get around this?

I have (before trying to covert to a parallel.foreach loop) split my list of objects that I am foreach looping through into four groups (separate csv files) and run four concurrent instances of my program (which ran faster overall than just one, thus the idea for parallel). So it seems connecting to the db shouldn't be a problem?

Any ideas?

EDIT: Here's before

var gtgGenerator = new CustomGtgGenerator();
var connectionString = ConfigurationManager.ConnectionStrings["BioEntities"].ConnectionString;

var allAccessionsFromObs = _GetAccessionListFromDataFiles(collectionId);

ForEach(cloneIdAndAccessions in allAccessionsFromObs)
    DoWork(gtgGenerator, taxonId, organismId, cloneIdAndAccessions, connectionString));

after

var gtgGenerator = new CustomGtgGenerator();
var connectionString = ConfigurationManager.ConnectionStrings["BioEntities"].ConnectionString;

var allAccessionsFromObs = _GetAccessionListFromDataFiles(collectionId);

Parallel.ForEach(allAccessionsFromObs, cloneIdAndAccessions => DoWork(gtgGenerator, taxonId, organismId, cloneIdAndAccessions, connectionString));

Inside the DoWork I use the BioEntities

using (var bioEntities = new BioEntities(connectionString)) {...}

It gets curiouser and curiouser...

I added some code in my DoWork method:

Debug.WriteLine(“Executing “ + itemName + ” as “ + WindowsIdentity.GetCurrent().Name);

and it mysteriously started working (quite well/fast actually). But eventually I got the same excepetion (after about an hour). But I was able to trace this..?

A first chance exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll

EDIT2: Hmm.. I came in to work and fired it up this morning (obsessed with understanding why it would work for a little bit) and it is cruising along working fine (and fast!) so far. Occasional : The thread '' (0x27c8) has exited with code 0 (0x0). The thread '' (0x26b8) has exited with code 0 (0x0).

But other than that it hasn't messed up yet? Which, frankly, just worries me more. This is a one-off thing so I may use it (if it works), but what is going on? Could it be NLOG, logging in the multiple threads clogs stuff up and causes timeouts in the sql? I really don't get it. Once it stops working again, I'll try to figure things out. Is there a way to reset the sql server, I'm not sure why it would work for an hour, then mess up, then never work for more than a couple seconds, and now (after a reboot) work (for about 30 minutes so far)?

shawn.mek
  • 1,195
  • 1
  • 11
  • 17
  • Related question http://stackoverflow.com/questions/10007535/tpl-task-in-wcf-service-fails-to-use-correct-iis-security-credentials-sql-conne and http://robseder.wordpress.com/2012/04/07/asp-net-impersonation-and-parallel-foreach-issue/ and http://social.msdn.microsoft.com/Forums/pl-PL/parallelextensions/thread/a1da0143-919c-433d-9d50-83795879082d – user7116 Jul 07 '12 at 21:11
  • Neither of the suggestions in the link had any effect. – shawn.mek Jul 07 '12 at 21:14
  • Okay! Well this is freaky? I tried all these different suggestions with no success. Then I decided to try this code from the robseder.wordpress.com link :Debug.WriteLine("Executing " + cloneIdAndAccessions.Item1.ToString() + " as " + WindowsIdentity.GetCurrent().Name) I wanted to see what usernames were looking like. And wouldn't you know it. It just works now? I don't even have the passing of identities, etc. I ONLY added that code. Weird!? – shawn.mek Jul 08 '12 at 04:20
  • frustrating - it worked so well that one time? Now I'm back to never getting past a minute? – shawn.mek Jul 08 '12 at 06:35

2 Answers2

2

Your identity isn't flowing to the worker thread executing the underlying tasks of your parallel for.each.

The answer here is a good one, so I won't duplicate it. TPL Task in WCF service fails to use correct IIS security Credentials (SQL Connection)

Community
  • 1
  • 1
Kenneth Ito
  • 5,201
  • 2
  • 25
  • 44
  • IIRC there's some policy to include the relevant bit of the link in case the target link goes away (which could happen even for SO questions, AFAICT)? – James Manning Jul 07 '12 at 19:58
  • Hmm, even for SO references? I wouldn't be surprised if this was closed later as exact duplicate to the link I gave. – Kenneth Ito Jul 07 '12 at 20:08
  • Well, neither of the two choices worked, so maybe I'm not clear on how I can get the identity to flow to the Parallel.Foreach task, or it's something totally different? – shawn.mek Jul 07 '12 at 20:52
  • @KennethIto: you don't answer with a link to another answer on SO. You vote to close as a dupe or add it as a comment. – user7116 Jul 07 '12 at 21:11
  • @sixlettervariables. Noted. Though I can't vote to close as dupe, I guess the preferred way is a comment then. – Kenneth Ito Jul 07 '12 at 21:15
  • @shawn.mek You did capture the identity from the outer context right? You need to pass in the identity. – Kenneth Ito Jul 07 '12 at 21:20
  • tried passing it in, tried a bunch of other permutations. I'll try printing out the identity for each thread to see what's going on. This seems a little wild/random the way it's handling things. – shawn.mek Jul 07 '12 at 21:36
  • Hrmm, could this be a delegation scenario? You are connecting to the database as the current user right? – Kenneth Ito Jul 07 '12 at 21:54
  • I'm not sure what you mean by delegation scenario. I printed out what ident each thread was using, that seems to be all good. I'll dig in to figure this out in the future if I have time, wish it would have worked :-) – shawn.mek Jul 08 '12 at 23:03
  • You situation on the worker threads is similar to this. http://stackoverflow.com/questions/1981414/asp-net-windows-authentication-to-sql-server . We are impersonating an identity and then flowing the identity over to sql server. Delegation allows sql server to trust the identity. – Kenneth Ito Jul 08 '12 at 23:14
  • I'm pretty sure it isn't an identity problem. But I'll keep trying any suggestions I get. – shawn.mek Jul 09 '12 at 02:58
  • Hrmm, I'll try to find the time to setup an environment to test/repro on. May be a little though, need to set up a domain controller and a domain member (I think domain controllers implicitly have delegation rights so I can't test there). – Kenneth Ito Jul 09 '12 at 03:02
1

Okay sorry for answering my own question, but it might be valuable to someone, somewhere, sometime.

Upon adding (and subsequently removing) the following code in order to see what identity each thread was using, the 'login failed' error never occurred again. I'm not sure if using it affected something, but I don't use it now and it never seems to have the identity problem discussed in the links and answers that were initially given.

Debug.WriteLine("Executing " + cloneIdAndAccessions.Item1.ToString() + " as " + WindowsIdentity.GetCurrent().Name);

There must have been two problems going on here, and the first was masking the latter. But I was still getting the following two types of connection errors. Particularly (I noticed) after opening SQL Server Management Studio and perhaps straining the server.

System.Data.EntityCommandExecutionException: An error occurred while reading from the store provider's data reader. See the inner exception for details. ---> System.Data.SqlClient.SqlException: The query processor could not start the necessary thread resources for parallel query execution.

And...

System.Data.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details. ---> System.Data.SqlClient.SqlException: Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.

So, my solution (since I could not find rhyme nor reason to when the errors would arise) was to simply catch the errors and record which object in the Parallel.ForEach loop threw it, then rerun those objects. Still MUCH faster than the simple foreach loop.

EDIT: Well, this is interesting, I found some rhyme/reason to the errors (not when they are thrown but maybe why). If I chunk the number of objects in my Parallel.ForEach loop into smaller (10,000 objects as opposed to 100,000) groups then I never got any exceptions thrown. NICE.

So the summary - check identity, then maybe break up your groups being run in the foreach loop... and someone figure out why this is necessary and report back :)

EDIT /end

Not the greatest solution, but relatively simple as compared to delving deeper into tasks and thread craziness.

shawn.mek
  • 1,195
  • 1
  • 11
  • 17