0

I'm running this thread inside a method from a WCF service library.

The code below is executed at the end of the method. I do this because i don't want the user to wait for a background process to complete that does not affect the output from the WCF to the client.

The problem that i have now is that if i execute that thread and the client gets the response, the parent thread is killed; killing this thread as well. How do i make it so that the parent thread waits for this thread to finish, while performing the rest of the operations?

         class Program
{
    static void Main(string[] args)
    {
        Dictionary<string, string> sampleDict = getPopulatedDictionary();
        var result = run(sampleDict);
    }

    public static int run(Dictionary<string, string> sampleDict_)
    {

        PerformCalculations(sampleDict_);
        if (sampleDict_.Keys.Count > 10)
        {
            System.Threading.Tasks.Task.Factory.StartNew(() =>
            {
                backgroundprocess(sampleDict_);
            });
        }
        //after returning i still want it to run
        return sampleDict_.Keys.Count;
    }

    private static void backgroundprocess(Dictionary<string,string> dict)
    {
        foreach (var k in dict.Keys)
        {
            dict[k] = new Random().Next(2666).ToString();
        }
    }
}

In short, i want this method to kick off that thread and move onto return the value X but still wait for that thread to finish AFTER it returns the value.

Ramie
  • 1,171
  • 2
  • 16
  • 35
  • for apply of Task, much more of detail return order of value process is needed. please,, consider call of synchronons :) – PRASHANT P Mar 19 '13 at 18:41

3 Answers3

1

If you aren't going to do anything except wait for the background thread to complete, then you might as well just not create the new background thread in the first place and execute the code in-line.

Servy
  • 202,030
  • 26
  • 332
  • 449
  • so its not possible to return a value and then start a thread and wait for it? The reason this case is different is because the data needs to be sent to the client as quick as possible. So waiting for the whole thing to complete would take more time. – Ramie Mar 19 '13 at 18:42
  • @Ramie Well, your statement that the parent thread finishing will stop this thread is inherently not correct. The parent thread *doesn't* need to stick around for this thread to continue. The process can't end, but in your case I highly doubt the entire process is finishing. My guess is that you're accessing some request or response information from within the background task that is only valid while the execution context exists. It's also possible that you're using a DBContext that is being disposed of when execution continues. – Servy Mar 19 '13 at 18:46
  • any idea on how i can ma it so it does not stick around for this thread to continue? – Ramie Mar 19 '13 at 18:48
  • @Ramie Without knowing much more about what exactly it's doing I couldn't say. – Servy Mar 19 '13 at 18:51
  • I posted some code hopefully it will give you a better understanding of what i need – Ramie Mar 19 '13 at 19:00
  • @Ramie Well, for starters, you won't be getting random numbers when trying to generate them that way. [See here for details](http://stackoverflow.com/questions/767999/random-number-generator-only-generating-one-random-number). Next, when do you actually use the data you enter in the dictionary there? – Servy Mar 19 '13 at 19:03
  • no i just included it as a sample, don't worry about the random stuff. Uh the dictionary is used in the performcalculations method and to pass into the background process. – Ramie Mar 19 '13 at 19:09
  • @Ramie Yes, and the background process just sets a bunch of keys, which if there is nobody to read values from those keys does *nothing*. – Servy Mar 19 '13 at 19:10
  • i wrote this piece of code out just to provide a concept of my question. Does it really matter whether there is anybody to read the values from those keys? Its returning the keycount of it after some modifications, thats all the user needs to see (in the main method0 – Ramie Mar 19 '13 at 19:13
  • @Ramie If you are returning something that's based on the result of the background task then we're back to the text of the answer. You can't continue until the background task is done, so it's not a background task at all, don't create a new thread. If it's not based on the result of the background task then what is, if anything? – Servy Mar 19 '13 at 19:34
1

Couldn't you do it as a continuation of the parent task. So execute

FameMappingEntry.SaveFameDBMap(toSaveIdentifiers); as a continuation of a successful completion of the parent task. And then you can wait on the continutation.

var childTask = parentTask.ContinueWith((pt) =>
{
   FameMappingEntry.SaveFameDBMap(toSaveIdentifiers);
}, TaskContinuationOptions.OnlyOnRanToCompletion);

And then you can decide if you want to wait on the child task or use another continuation.

Neerav
  • 199
  • 1
  • 5
0

Try this:

var task = System.Threading.Tasks.Task.Factory.StartNew(() =>
{
  lock (toSaveIdentifiers)
  {
      FameMappingEntry.SaveFameDBMap(toSaveIdentifiers);
  }
);

int x = dosomething();

task.Wait();
return x;

You should also lock objects in the thread that uses them, and not some other random thread.

alex
  • 12,464
  • 3
  • 46
  • 67