Home HomeVisual C dla programujacych w Visual Basicuprogram%252Bzaj%2525C4%252599%2525C4%252587%25252C%252Bbibliografia%25252C%252Bwyk%2525C5%252582ad%252B01 03Emma Rothschild Economic Sentiments; Adam Smith, Condorcet, and the Enlightenment (2002)Routledge Critical Thinkers Adam Roberts Fredric Jameson (2000)Friedrich Nietzsche Wola mocy by adam xyzRoss Adam Ciemna strona małżeństwa[JoannaC]Bahdaj Adam Podroz za jeden usmiech.BLACKAdam Carpenter 02 Rapture in RomeBodor Adam Z powrotem do uszatej sowyKnight Harry Adam Pochodnia
 

[ Pobierz całość w formacie PDF ]
.SolutionThe only way to avoid this problem is to ensure that your Tasks do not depend on one another.Thisrequires careful attention when writing your Task bodies and thorough testing.You can also use thedebugging features of Visual Studio 2010 to help detect deadlocks (see Chapter 7 for details).ExampleIn the following example, two Tasks depend upon one another, and each requires the result of the otherto generate its own result.When the program is run, both Tasks are started by the main applicationthread and deadlock.Because the main thread waits for the Tasks to finish, the whole program seizes upand never completes.using System;using System.Threading.Tasks;namespace Dependency_Deadlock {class Dependency_Deadlock {static void Main(string[] args) {// define an array to hold the TasksTask[] tasks = new Task[2];// create and start the first tasktasks[0] = Task.Factory.StartNew(() => {// get the result of the other task,// add 100 to it and return it as the resultreturn tasks[1].Result + 100;});// create and start the second tasktasks[1] = Task.Factory.StartNew(() => {// get the result of the other task,// add 100 to it and return it as the resultreturn tasks[1].Result + 100;});45 CHAPTER 2 % TASK PROGRAMMING// wait for the tasks to completeTask.WaitAll(tasks);// wait for input before exitingConsole.WriteLine("Main method complete.Press enter to finish.");Console.ReadLine();}}}Local Variable EvaluationAssume that you create a series of Tasks in a for loop and refer to the loop counter in your lambdaexpressions.All of the Tasks end up with the same value because of the way that the C# variable scopingrules are applied to lambda expressions.SolutionThe simplest way to fix this problem is to pass the loop counter in as a state object to the Task.ExampleIn the following example, five Tasks print out a message that references the counter of the loop thatcreated them, and they all print the same value.Another five Tasks do the same thing, but get theirvalues as state objects, and these get the expected values.using System;using System.Threading.Tasks;namespace Local_Variable_Evaluation {class Local_Variable_Evaluation {static void Main(string[] args) {// create and start the "bad" tasksfor (int i = 0; i {// write out a message that uses the loop counterConsole.WriteLine("Task {0} has counter value: {1}",Task.CurrentId, i);});}// create and start the "good" tasksfor (int i = 0; i {// cast the state object to an intint loopValue = (int)stateObj;46 CHAPTER 2 % TASK PROGRAMMING// write out a message that uses the loop counterConsole.WriteLine("Task {0} has counter value: {1}",Task.CurrentId, loopValue);}, i);}// wait for input before exitingConsole.WriteLine("Main method complete.Press enter to finish.");Console.ReadLine();}}}Excessive SpinningMany programmers overestimate the performance impact of a Task waiting (either via Thread.Sleep() orby using a CancellationToken wait handle) and use spin waiting instead (through the Thread.SpinWait()method or by entering a code loop).For anything other than exceptionally short waits, spin waiting and code loops will cripple theperformance of your parallel program, because avoiding a wait also avoids freeing up a thread forexecution.SolutionRestrict your use of spin waiting and code loops to situations where you know that the condition thatyou are waiting for will take only a few CPU cycles.If you must avoid a full wait, use spin waiting inpreference to code loops.ExampleIn the following example, one Task enters a code loop to await the cancellation of another Task.AnotherTask does the same thing but uses spin waiting.On the quad-core machine that I used to write this book,this example burns roughly 30 percent of the available CPU, which is quite something for a program thatdoes nothing at all.You may get different results if you have fewer cores.using System;using System.Threading;using System.Threading [ Pobierz całość w formacie PDF ]