我有一个非常人为的问题。
想象一下,我有一个只有一个方法和一个字段的类。像:
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()方法,直到它完成。
我假设我必须在一个新线程上执行此操作,然后进入交叉线程的世界?然后我认为我的设计一定是错的,我已经过度复杂了!
任何人都会关注这个意见或建议吗?
谢谢
答案 0 :(得分:4)
假设此代码在UI线程上运行,它可以直接在循环内更新UI。但是,如果不想将UI代码与业务逻辑混合(这是一个好主意),那么您将需要在另一个线程上运行此处理并让UI线程检查此对象,或者最好将事件通知作为任务进行。
您应该考虑使用BackgroundWorker来处理。这个类可以简化这样的处理任务,并包含支持进度指示器的逻辑。
MSDN文章中的示例代码显示了如何通过拖放到设计图面上来设置大量内容(假设您使用的是WinForms),以及如何将BackgroundWorker链接到进度条。
答案 1 :(得分:1)
这是一个使用ThreadPool进行线程处理的基本示例:
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
答案 2 :(得分: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();