我简化了一下,把代码贴在下边。
Form1是主窗体,frmWeb是含有WebBrower的窗体(登录器)。
在Form1中开启多个线程,在每个线程中打开Web窗体,通过从主窗体中传过去的帐号信息,实现自动登陆。
登录之后,通过在frmWeb中加的事件TaskReport,报告登录是否完成等信息。
由于BackGroundWorker不支持WebBrowser,就用Thread建立STA线程。现在问题是:如何才能在各个STA线程中顺利运行frmWeb?
1) 用task.webForm.Show(),窗体一闪而过;
2) 用task.webForm.ShowDialog(),可以打开多个,但是登录的都是同一个帐号,感觉Show了以后,卡在Break了;
3) 用Application.Run,相当于运行完全转到frmWeb了。如何才能实现想要的功能?因为主窗体和Web窗体之间还有交互,不想在另外的进程中开启Web窗体。
public partial class Form1 : Form
{
public class TaskArg
{
public string loginID;
public string password;
public Thread thread;
public frmWeb webForm;
} public List<TaskArg> lstTask = new List<TaskArg>();
string[] loginIDs = new string[] { 省略 };
string[] password = new string[] { 省略 }; public Form1()
{
InitializeComponent();
} void CreateThreadWeb()
{
for (int i = 0; i < loginIDs.Length; i++)
{
TaskArg task = new TaskArg();
task.loginID = this.loginIDs[i];
task.password = this.password[i];
task.thread = new Thread(ThreadProc);
task.thread.SetApartmentState(ApartmentState.STA);
lstTask.Add(task);
task.thread.Start(task);
}
} void ThreadProc(object taskArg)
{
TaskArg task = taskArg as TaskArg;
//lock (this.lstTask)
{
int i = lstTask.Count - 1;
for (; i >= 0; i--)
if (lstTask[i].Equals(task))
{
task.webForm = new frmWeb(task.loginID, task.password );
task.webForm.TaskReport += new ProgressChangedEventHandler(webForm_TaskReport);
task.webForm.ShowDialog();
//task.webForm.Show();
//Application.Run(task.webForm);
break;
}
}
} void webForm_TaskReport(object sender, ProgressChangedEventArgs e)
{
//
}
}
Form1是主窗体,frmWeb是含有WebBrower的窗体(登录器)。
在Form1中开启多个线程,在每个线程中打开Web窗体,通过从主窗体中传过去的帐号信息,实现自动登陆。
登录之后,通过在frmWeb中加的事件TaskReport,报告登录是否完成等信息。
由于BackGroundWorker不支持WebBrowser,就用Thread建立STA线程。现在问题是:如何才能在各个STA线程中顺利运行frmWeb?
1) 用task.webForm.Show(),窗体一闪而过;
2) 用task.webForm.ShowDialog(),可以打开多个,但是登录的都是同一个帐号,感觉Show了以后,卡在Break了;
3) 用Application.Run,相当于运行完全转到frmWeb了。如何才能实现想要的功能?因为主窗体和Web窗体之间还有交互,不想在另外的进程中开启Web窗体。
public partial class Form1 : Form
{
public class TaskArg
{
public string loginID;
public string password;
public Thread thread;
public frmWeb webForm;
} public List<TaskArg> lstTask = new List<TaskArg>();
string[] loginIDs = new string[] { 省略 };
string[] password = new string[] { 省略 }; public Form1()
{
InitializeComponent();
} void CreateThreadWeb()
{
for (int i = 0; i < loginIDs.Length; i++)
{
TaskArg task = new TaskArg();
task.loginID = this.loginIDs[i];
task.password = this.password[i];
task.thread = new Thread(ThreadProc);
task.thread.SetApartmentState(ApartmentState.STA);
lstTask.Add(task);
task.thread.Start(task);
}
} void ThreadProc(object taskArg)
{
TaskArg task = taskArg as TaskArg;
//lock (this.lstTask)
{
int i = lstTask.Count - 1;
for (; i >= 0; i--)
if (lstTask[i].Equals(task))
{
task.webForm = new frmWeb(task.loginID, task.password );
task.webForm.TaskReport += new ProgressChangedEventHandler(webForm_TaskReport);
task.webForm.ShowDialog();
//task.webForm.Show();
//Application.Run(task.webForm);
break;
}
}
} void webForm_TaskReport(object sender, ProgressChangedEventArgs e)
{
//
}
}
2. task.webForm.ShowDialog()可以显示,是因为ShowDialog()的退出需要接受输入的值才能做出响应,如果没有输入则一直等待,这就是为什么你能看到窗体;
3. Application.Run的原因与上面类似,执行后同样等待你的发送close消息才能关闭。若要使用.Show()方法可用,请使用委托。如下:
1) 定义委托
private delegate void myDelegate(taskArg task);2)在ThreadProc方法中将task.webForm.Show();语句替换为:
myDelegate dl = new myDelegate(showFrm);3)定义showFrm方法
void showFrm(TaskArg task)
{
task.webForm.Show();
}
多谢楼上的回复。
我测试了一下,这里用不用委托结果都是一样的。我想了一下,这里不能用Show()的,应该用ShowDialog或Run。因为这实际上是在子线程中。比如是frmWeb运行完了关闭后才能到break的。现在问题就变成了如何独立Cookie的问题了。就是说打开几个窗体后,总是登录同一个帐号。
如何登录不同账号?
可以取到不同的帐号,但是登录出来都是同一个帐号。WebBrower的Cookie是共享的。
不知道怎么解决一个程序(进程)中,如何让多个Web窗口可以登录不同的帐号,就是说Cookie相互独立。
可以看看MSDN修改和删除cookie一节:
http://msdn.microsoft.com/zh-cn/library/ms178194.aspx