您的位置:首页 > 理论基础 > 计算机网络

c#多线程网络请求,等待所有线程完成后更新UI

2018-01-15 19:02 411 查看
最近项目中需要循环进行网络请求拉取用户信息(每个用户信息都需要一次网络请求),拉取完成后需要通知界面更新UI。实现方法是使用C#提供的ManualResetEvent,相当于一个标记,在每个线程中插入这个标记。再启动一个线程循环监听这个标记,直到所有线程都执行完毕则更新UI。

public  List<WxUserInfo> GetAllUerInfo(StringCollection userlist)
{
WxUserList = new List<WxUserInfo>();
//为每个线程创建一个ManualResetEvent对象
_ManualEvents = new ManualResetEvent[userList.Count];
int i = 0;

foreach (string openid in userList)
{
_ManualEvents[i] = new ManualResetEvent(false);
WXOBJ wxobj = new WXOBJ(_ManualEvents[i], openid);
i++;
//加入线程池
ThreadPool.QueueUserWorkItem(new WaitCallback(GetUserInfo), (object)wxobj);
}
//再启动一个线程监听其他线程执行状态
Thread t = new Thread(NotifyUI);
t.Start();
return WxUserList;
}


private  void NotifyUI(object obj)
{
//等待所有线程释放_ManualEvents
WaitHandle.WaitAll(_ManualEvents);
//监听线程有时会抢先通知UI更新,所以这里让线程睡了1秒才通知更新
Thread.Sleep(1000);
WxUserInfo[] allWxUser = WxUserList.ToArray();
//切换UI线程更新UI
Action<DataGrid, List<WxUserInfo>> updateAction = new Action<DataGrid, List<WxUserInfo>>(UpdateListView);
Information.Dispatcher.BeginInvoke(updateAction, Information, allWxUser.ToList());
var suto = new ManagerService.ManagerServiceClient().InsertWxUserInfoAsync(allWxUser);
}


/// <summary>
/// 创建一个对象封装manualResetEvent,和线程方法需要的参数
/// </summary>
public class WXOBJ
{
public ManualResetEvent manualResetEvent { set; get; }

4000
public string openid { set; get; }

public WXOBJ(ManualResetEvent manualResetEvent, string openid)
{
// TODO: Complete member initialization
this.manualResetEvent = manualResetEvent;
this.openid = openid;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C# 多线程