2012-10-22 51 views
1

我有一个非常人为的问题。我的循环迭代了多少次

想象一下,我有一个只有一个方法和一个字段的类。像:

public class WhereAmI 
{ 
    public int Number = 0; 
    public void Looping() 
    { 
     for (int i = 0; i < 100; i++) 
     { 
      Number = i; 
      Sleep(10000); 
     } 
    } 
} 

我把它从以正常方式另一个类,你会期望

WhereAmI wai = new WhereAmI(); 
wai.Looping(); 
int CurrentNumber = wai.Number; 

我要的是一个方法,看看我是什么号码目前最多,并显示在屏幕上。我已经尝试了类似于上述内容,但这不起作用,因为编译器在完成之前不会移过wai.Loopping()方法。

我假设我必须在一个新的线程上做这件事,然后进入跨线程的世界?然后我认为我的设计一定是错的,我已经把这个过于复杂了!

任何一个人都会在意他们的意见或建议吗?

谢谢

回答

4

假设这段代码是在UI线程运行它可能只是直接在循环中更新UI。但是,如果不想将UI代码与业务逻辑混合(这是一个好主意),那么是的,您需要在另一个线程上运行此处理,并让UI线程检查此对象,或者最好将事件通知作为任务进展。

您应该看看使用BackgroundWorker来处理处理。这个类使得处理任务像这样变得更简单,并且包含支持进度指示符的逻辑。

MSDN文章中的示例代码展示了如何通过拖放到设计界面(假设您使用WinForms)来设置大量此类事件,以及如何将BackgroundWorker链接到进度栏。

1

下面是使用线程池做穿线一个基本的例子:

void Main() 
{ 
    var pooling = new JustPooling(); 

    pooling.RunThread(); 

    Thread.Sleep(500); 

    while (pooling.Operating) 
    { 
     Console.Write (" " + pooling.CurrentIndex); 
     Thread.Sleep(500); 
    } 

    Console.Write(" Done"); 
    /* 1 1 2 2 2 3 3 3 4 4 4 5 5 5 Done */ 


} 

// Define other methods and classes here 

public class JustPooling 
{ 
    public bool Operating { get; set; } 
    public int CurrentIndex { get; set; } 

    public void RunThread() 
    { 
     ThreadPool.QueueUserWorkItem(delegate 
     { 
      Operating = true; 

      for (int index = 0; index < 5; ++index) 
      { 
       ++CurrentIndex; 
       Thread.Sleep(1500); 
      } 

      Operating = false; 
     }); 
    } 

} 

要查看与临界区看到C# MultiThreading Using ThreadPool, Anonymous Delegates and Locks

1

使用回调或事件处理程序,以确保一切就锁定这个例子同一个线程。

回调:

public void Looping(Action onIncrement) 
{ 
    for (int i = 0; i < 100; i++) 
    { 
     Number = i; 
     onIncrement(); 
     Sleep(10000); 
    } 
} 

obj.Looping(() => Console.WriteLine(obj.Number)); 

事件处理程序:

public event EventHandler Increment; 

public void Looping() 
{ 
    for (int i = 0; i < 100; i++) 
    { 
     Number = i; 
     if (Increment != null) 
     { 
      Increment(this, EventArgs.Empty); 
     } 
     Sleep(10000); 
    } 
} 

obj.Increment += (s, e) => Console.WriteLine(obj.Number); 
obj.Looping();