2013-04-15 47 views
1

我正在学习TPL C#,当我在一个任务中调用一个无限的while循环时,它会终止任何错误。难道我做错了什么?下面是示例代码。连续while循环在任务中

class Work2 
{ 
    public void DoWork() 
    { 
     List<string> scenarios = new List<string>(); 
     scenarios.Add("work"); 
     scenarios.Add("climb"); 
     scenarios.Add("walk"); 
     scenarios.Add("run"); 

     List<int> id = new List<int>(); 
     id.Add(1); 
     id.Add(2); 
     id.Add(3); 
     id.Add(4); 

     for (int i = 0; i < 2; i++) 
     { 
      Task.Factory.StartNew(() => 
      { 
       workInstance(id[i], scenarios); 
      }, TaskCreationOptions.LongRunning); 

      Thread.Sleep(500); 
     }  
    } 

    public void workInstance(int id, List<string> scenario) 
    { 
     string Guid = System.Guid.NewGuid().ToString(); 
     for (int i = 0; i < scenario.Count(); i++) 
     { 
      scenario[i] = scenario[i] + " " + Guid + " " + Thread.CurrentThread.ManagedThreadId; 
     } 

     while (true) 
     { 
      for (int i = 0; i < scenario.Count(); i++) 
      { 
       Console.WriteLine(scenario[i]); 
      } 
     } 
    }   
} 
+0

如果您从Main()调用此函数,那么它可能会在1秒钟后自然终止(2 x 500ms)。注意:你要小心你的无限循环。这是一个紧凑的环境,可以占用100%的CPU资源。 – joshgo

+0

上面的程序在work2.cs中Main我只是调用work2 wrk = new work(); wrk.dowork();这就是我所做的一切。而不是我使用正常线程的任务,我没有看到这个问题。正如我所说,我只是试验不为应用程序,所以不真正关心100%cpu – kumar

回答

2

的问题是,你不等待Task s到完成。当所有的前景Thread氏完全。如果手动创建一个Thread,默认情况下它是作为一个前台线程创建的Process结束,所以你的应用程序将不会结束,直到你创建的Thread就做。

Task s为(默认)在后台线程运行(即使您指定LongRunning)。这意味着你会结束,即使有一些Task s仍在运行。

你应该怎么做才能解决这个问题,就是等待所有的Task完成。例如:

var tasks = new Task[2]; 

for (int i = 0; i < 2; i++) 
{ 
    tasks[i] = Task.Factory.StartNew(() => 
    { 
     workInstance(id[i], scenarios); 
    }, TaskCreationOptions.LongRunning); 
} 

Task.WaitAll(tasks); 
+0

很好! +1 –

1

这是一个无限循环,你想,请检查下面的代码

static void Main(string[] args) 
{ 
    Work2 w = new Work2(); 
    w.DoWork(); 
    Console.ReadKey(); 
} 

注意,我加入了,下面的代码Console.ReadKey();

我现在看到正在打印的输出和它仍然是我的PC :)上运行的滚动窗口

调试你的代码,你将看到线程被称为在workInstance方法有

Thread.CurrentThread.IsBackground=true 

当主线程退出,即你的应用程序退出时,.NET Framework将自动杀死其的IsBackground属性设置为任何线程“真”

对于您引用,

线程可以是一个背景线程或前台线程。后台线程与前台线程完全相同,只是后台线程不会阻止进程终止。一旦属于某个进程的所有前台线程都终止,公共语言运行库就结束该进程。

+0

这确实解释了发生了什么,但它也会说如何解决它。 – svick

+0

@svick我相信他正在学习,并在他的例子中发起了一个无限循环,并希望得到帮助,以了解为什么它会终止。如果他不希望应用程序终止,那么就像我说的那样,他可以调用Console。ReadKey()或在他的workInstance方法中设置Thread.CurrentThread.IsBackground = false。如果你认为这个问题是在消除一个无限循环,那么这个问题将不得不为此重新说明。 –

+0

这正是你不应该做的。在ThredPool线程上设置'IsBackground'是一种不好的做法,因为它不是你的线程。 – svick