目前正在做一个Winform的项目,开发环境vs2010.
项目中需要同时开4个线程来进行不同的数据传输, 这4个线程执行时间各不相同, 当4个线程都执行完毕后,进入下一轮数据传输 (还是用4个线程 传输不同的下一轮数据)。 这个过程中,不能block GUI界面。我的想法用thread pool中4个线程, 用volatile int numberOfFinished 这个变量来检查每一轮4个线程是不是都结束了. 不知道有没有更好的方法。请大家给出意见。谢谢了先。
项目中需要同时开4个线程来进行不同的数据传输, 这4个线程执行时间各不相同, 当4个线程都执行完毕后,进入下一轮数据传输 (还是用4个线程 传输不同的下一轮数据)。 这个过程中,不能block GUI界面。我的想法用thread pool中4个线程, 用volatile int numberOfFinished 这个变量来检查每一轮4个线程是不是都结束了. 不知道有没有更好的方法。请大家给出意见。谢谢了先。
IAsyncResult 来判断也可以
回调函数就更好了
using System.Threading;namespace ConsoleApplication1
{
class Program
{
private static object asyncLock = new object(); public static Int32 _NumberOfFinished;
public static Int32 NumberOfFinished
{
get
{
return _NumberOfFinished;
} set
{
_NumberOfFinished = value; if (_NumberOfFinished == 4)
{
Console.WriteLine("所有线程完成,两秒后自动继续");
System.Threading.Thread.Sleep(2000);
Start();
}
}
} static void Main(string[] args)
{
Start(); Console.ReadLine();
} static void Start()
{
NumberOfFinished = 0;
for (Byte i = 0; i < 4; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Foo), i);
}
} static void Foo(Object obj)
{
Int32 z = Byte.Parse(obj.ToString());
for (Int32 i = 0; i < 500; i++)
{
Console.WriteLine(i);
} lock (asyncLock)
{
NumberOfFinished++;
}
}
}
}垃圾方法
主线程(或监控线程)使用WaitHandle.WaitAll(evnt1到4的数组)来判断四个事件是不是都标志了Set,如果是,则进入下一轮(用autoresetevent会自动reset),否则主线程将等待直到四个事件全部set
这个方法我也想过,但是要保证UI的响应,必须开另外一个控制线程,在控制线程中来处理四个线程。而且这四个线程还需要和UI主线程来通信。 我担心控制不好会更麻烦。 不知道大家意见如何?
http://stackoverflow.com/questions/12811924/multithread-control-of-net-winform-app?answertab=votes#tab-top
DWORD nCount,
CONST HANDLE* lpHandles,
BOOL fWaitAll,
DWORD dwMilliseconds
);Dllimport这个function,这个是windows API绝对靠谱
1、ManualResetEvent、AutoResetEvent
2、Thread、ThreadStart
3、Invoke, delegate可以灵活应付线程操作。
Barrier这个类型的文档里面有例子,另外线程同步的一个专题里面也有Barrier的例子。
http://www.google.com.hk/#hl=zh-CN&lr=lang_zh-CN%7Clang_zh-TW&newwindow=1&safe=strict&tbs=lr:lang_1zh-CN%7Clang_1zh-TW&spell=1&q=.net+waithandle+waitall&sa=X&ei=2NZ2UPbMNIWfiAePkIGIAQ&ved=0CC8QvwUoAA&bav=on.2,or.r_gc.r_pw.&fp=5aa343445015814f&biw=1378&bih=844
主线程中声明WaitHandle[] finishedEvts = new WaitHandle[4]; //new ManaulResetEvent(false)
4个子操作中执行完后Set()
主线程将子操作全部排入UserWorkQueue之后,
调用WaitHandler.WaitAll(finishedEvts, 5000)阻塞5000ms,只有它们全部执行完时才会返回True
问题是:在主线程(UI线程)中使用join会阻塞界面响应。包括用WaitAll(),WaitForMultipleObjects API ,什么的也都是这个问题。
如果在UI线程中Wait/Join/Sleep,会阻塞UI的响应。 如果在控制线程中创建四个子线程,和UI线程的交互(比如显示进度条信息)就会成问题。
但这种方法感觉不好,不知道你有什么建议?谢谢了
这个会阻塞主线程UI,不可行。 目前主线程UI不允许任何形式的阻塞,问题难点在这里呀。
1)数据的线程安全
2)线程同步
3)死锁
因为主线程/UI操作通常是线程不安全的,所以,.net使用线程同步来解决。关于主线程/UI和子线程同步的例子很多,你搜索一下就找到了。
#10楼,使用信号量,很好的解决了你需要4个线程同步,建议每个线程判断:WaitHandle.WaitAll(evnt1到4的数组).....。这样,不需要控制线程。
另开一线程调用waitformultipleobjects,具体去找MSDN,windows核心编程也行。