c# - c# 在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke System.Threading.Thread
问题描述
不是Windows下的线程专家。我有一个 Main WinForm 在它的 ctor 中打开一个子表单。
public partial class Main : Form
{
public Main()
{
InitializeComponent();
ImgRxUI formStart = new ImgRxUI();
formStart.MdiParent = this;
formStart.WindowState = FormWindowState.Maximized;
formStart.Show();
}
ETC..
ImgRxUI 表单(子表单)启动一个传递给 2 个操作(简单形式的委托)的线程。
public partial class ImgRxUI : Form
{
private ImgReceiver oImgReceiver = null;
public ImgRxUI()
{
InitializeComponent();
this.WindowState = FormWindowState.Maximized;
this.ShowIcon = false;
oImgReceiver = new ImgReceiver(UpdateImage, Log);
oImgReceiver.startService();
}
public void UpdateImage(byte[] ProtocolType)
{
...do stuff...
}
public void Log(string Text)
{
this.Invoke((MethodInvoker)delegate
{
LogMethod(Text);
tLog.ScrollToCaret();
});
}
private void LogMethod(string Text)
{
tLog.AppendText(Text + Environment.NewLine);
}
正如我所说的 ImgReceiver 启动了一个在套接字上侦听的线程......
public class ImgReceiver
{
private Action<byte[]> ImgReceived;
private Action<string> Log;
private System.Threading.Thread Thread_ImgReceiver = null;
public ImgReceiver(Action<byte[]> ImageReceivedDelegate, Action<string> LogDelegate)
{
this.ImgReceived = ImageReceivedDelegate;
this.Log = LogDelegate;
}
public void startService()
{
Thread_ImgReceiver = new System.Threading.Thread(startListening);
Thread_ImgReceiver.IsBackground = true;
Thread_ImgReceiver.Start();
}
[SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)]
public void killService()
{
Thread_ImgReceiver.Abort();
System.Threading.Thread.Sleep(1000);
}
public void startListening()
{ ...do stuff...}
当我关闭 ImgRxUI 表单时,表单本身的以下事件被调用
private void ImgRxUI_FormClosing(object sender, FormClosingEventArgs e)
{
oImgReceiver.killService();
}
听起标题中的错误。
什么?
塔克斯
解决方案
将 kill Service 方法更改为
[SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)]
public void killService(Action action)
{
action.Invoke();
System.Threading.Thread.Sleep(1000);
}
将访问级别 Thread_ImgReceiver 更改为 public
public System.Threading.Thread Thread_ImgReceiver = null;
并调用 killService 到
private void ImgRxUI_FormClosing(object sender, FormClosingEventArgs e)
{
oImgReceiver.killService(new Action(delegate { oImgReceiver.Thread_ImgReceiver.Abort(); }));
}
推荐阅读
- c# - 您的应用程序已使用来自 Google Cloud SDK 或 Google Cloud Shell 的最终用户凭据进行身份验证...texttospeech.googleapis.com
- intellij-idea - Intellij Idea:摆脱html文件中每次打开方括号后生成的空间
- prolog - 如何在 DOSBOX TurboProlog 中使用 if then else 条件
- html - 去除折叠背景图像上方网站标题边缘的空白
- javafx - JavaFX中的不可见分隔符?
- machine-learning - 关于决策树的预测
- amazon-web-services - 如何使用 CentOS 上运行 Wildfly/JBoss 的事件接收来自 Amazon SNS 的推送通知?
- reactjs - 使用reactjs输入值时无法解决输入字段问题
- xamarin.forms - 当前的 .NET/Xamarin 是否存在 GetTextExtentPoint 等效性
- c# - ComboBox 中的 WPF MVVM 绑定,两个外键都引用同一个表