无法从 Child 表单调用参数化线程
Cant call ParametizedThread from Child Form
我正在开发 Client/server 应用程序。
在客户端应用程序中,我有一个主窗体,它是一个 MDI parent。
主窗体有一个 Load 事件,它创建一个 Child 窗体的新实例并使其可见。
此事件还将 Main 建立为 Child 的 MdiParent。
Child 表单是一个 sign-in 屏幕。
从 child 表单中,我创建了对 parent 的引用,以便能够从 parent.
调用方法
但是,在执行 MdiParent.RequestConnection 方法后,GUI 卡住了。
所以我尝试从线程执行该方法,但它不接受我的声明,即使我似乎遵循了正确的语法。
我不明白我做错了什么。请帮忙
主窗体
public partial class frmMainForm: Form
{
public frmMainForm()
{
InitializeComponent();
}
Thread runningClient;
public MyTcpClient client= new MyTcpClient ();
frmChildForm frmSignIn;
bool clientConnected;
private void frmMainForm_Load(object sender, EventArgs e)
{
clientConnected= false;
panelSidebar.Hide();
if(frmSignIn == null)
{
frmSignIn= new frmChildForm();
frmSignIn.MdiParent = this;
frmSignIn.Show();
}
}
public void TurnOnPanels()
{
panelSidebar.Visible = true;
panelSidebar.BringToFront();
}
public void RequestConnection(string username)
{
string serverRsp = client.Connect(username);
if(serverRsp.Equals("SUCCESS"))
{
MessageBox.Show("Signed In", "Welcome", MessageBoxButtons.OK, MessageBoxIcon.Information);
clientConnected = true;
frmSignIn.Close();
}
}
}
还有我的child表格
public partial class frmChildForm : Form
{
frmMainForm frmParent;
Thread clientRunning;
public frmChildForm()
{
InitializeComponent();
frmParent= (frmMainForm)this.MdiParent;
}
private void frmSignIn_FormClosing(object sender, FormClosingEventArgs e)
{
frmParent= (frmMainForm)this.MdiParent;
frmParent.TurnOnPanels();
}
private void btnSignIn_Click(object sender, EventArgs e)
{
if (txtSignInUsername.Text.Equals(""))
{
MessageBox.Show("No empty fields.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
//This is where it fails
clientRunning= new Thread(new ParameterizedThreadStart(frmParent.RequestConnection);
//"No Overload for RequestConnection matches delegate ParameterizedThreadStart"
//If I try to include the parameter inside that call, I get a "waiting for method //name" syntax error message instead.
clientRunning.Start(txtSignInUsername.Text.ToUpper());
}
}
private void frmSignIn_Load(object sender, EventArgs e)
{
frmParent = (frmMainForm)this.MdiParent;
}
}
我也尝试通过在 RequestConnection 中创建一个线程来从主窗体执行此操作,它应该在其中执行 client.Connect,但我遇到了同样的错误。
您需要解决一些问题
public void RequestConnection(object username) // changed parameter type
{
if (username == null)
throw new ArgumentNullException(nameof(username));
if (!(username is string))
throw new InvalidCastException("Expect string");// give proper message
string serverRsp = client.Connect(username.ToString());
if (serverRsp.Equals("SUCCESS"))
{
MessageBox.Show("Signed In", "Welcome", MessageBoxButtons.OK, MessageBoxIcon.Information);
clientConnected = true;
//this is require to solve cross-thread operation
if (this.InvokeRequired)
this.Invoke(new MethodInvoker(delegate ()
{
frmSignIn.Close();
}));
else
frmSignIn.Close();
}
}
需要在Form Load Event中获取MdiParent,并从Constructor中移除。
您的子表单加载事件/或使用父更改事件
private void FrmLogin_Load(object sender, EventArgs e)
{
frmParent = (MainForm)this.MdiParent;
}
ParametrizedThreadStart委托实际上接受一个对象作为参数。
因此您必须为其提供一个方法,该方法将对象作为参数,而不是字符串。在您的方法中,您将收到对象,检查它是否为字符串,然后将其转换为字符串。
我正在开发 Client/server 应用程序。 在客户端应用程序中,我有一个主窗体,它是一个 MDI parent。 主窗体有一个 Load 事件,它创建一个 Child 窗体的新实例并使其可见。 此事件还将 Main 建立为 Child 的 MdiParent。 Child 表单是一个 sign-in 屏幕。 从 child 表单中,我创建了对 parent 的引用,以便能够从 parent.
调用方法但是,在执行 MdiParent.RequestConnection 方法后,GUI 卡住了。 所以我尝试从线程执行该方法,但它不接受我的声明,即使我似乎遵循了正确的语法。 我不明白我做错了什么。请帮忙
主窗体
public partial class frmMainForm: Form
{
public frmMainForm()
{
InitializeComponent();
}
Thread runningClient;
public MyTcpClient client= new MyTcpClient ();
frmChildForm frmSignIn;
bool clientConnected;
private void frmMainForm_Load(object sender, EventArgs e)
{
clientConnected= false;
panelSidebar.Hide();
if(frmSignIn == null)
{
frmSignIn= new frmChildForm();
frmSignIn.MdiParent = this;
frmSignIn.Show();
}
}
public void TurnOnPanels()
{
panelSidebar.Visible = true;
panelSidebar.BringToFront();
}
public void RequestConnection(string username)
{
string serverRsp = client.Connect(username);
if(serverRsp.Equals("SUCCESS"))
{
MessageBox.Show("Signed In", "Welcome", MessageBoxButtons.OK, MessageBoxIcon.Information);
clientConnected = true;
frmSignIn.Close();
}
}
}
还有我的child表格
public partial class frmChildForm : Form
{
frmMainForm frmParent;
Thread clientRunning;
public frmChildForm()
{
InitializeComponent();
frmParent= (frmMainForm)this.MdiParent;
}
private void frmSignIn_FormClosing(object sender, FormClosingEventArgs e)
{
frmParent= (frmMainForm)this.MdiParent;
frmParent.TurnOnPanels();
}
private void btnSignIn_Click(object sender, EventArgs e)
{
if (txtSignInUsername.Text.Equals(""))
{
MessageBox.Show("No empty fields.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
//This is where it fails
clientRunning= new Thread(new ParameterizedThreadStart(frmParent.RequestConnection);
//"No Overload for RequestConnection matches delegate ParameterizedThreadStart"
//If I try to include the parameter inside that call, I get a "waiting for method //name" syntax error message instead.
clientRunning.Start(txtSignInUsername.Text.ToUpper());
}
}
private void frmSignIn_Load(object sender, EventArgs e)
{
frmParent = (frmMainForm)this.MdiParent;
}
}
我也尝试通过在 RequestConnection 中创建一个线程来从主窗体执行此操作,它应该在其中执行 client.Connect,但我遇到了同样的错误。
您需要解决一些问题
public void RequestConnection(object username) // changed parameter type
{
if (username == null)
throw new ArgumentNullException(nameof(username));
if (!(username is string))
throw new InvalidCastException("Expect string");// give proper message
string serverRsp = client.Connect(username.ToString());
if (serverRsp.Equals("SUCCESS"))
{
MessageBox.Show("Signed In", "Welcome", MessageBoxButtons.OK, MessageBoxIcon.Information);
clientConnected = true;
//this is require to solve cross-thread operation
if (this.InvokeRequired)
this.Invoke(new MethodInvoker(delegate ()
{
frmSignIn.Close();
}));
else
frmSignIn.Close();
}
}
需要在Form Load Event中获取MdiParent,并从Constructor中移除。
您的子表单加载事件/或使用父更改事件
private void FrmLogin_Load(object sender, EventArgs e)
{
frmParent = (MainForm)this.MdiParent;
}
ParametrizedThreadStart委托实际上接受一个对象作为参数。
因此您必须为其提供一个方法,该方法将对象作为参数,而不是字符串。在您的方法中,您将收到对象,检查它是否为字符串,然后将其转换为字符串。