C# 当用户单击“终止运行线程”;X";表单上的按钮
假设我有一个名为mainFrm的表单和一个名为objectA的对象,该对象保存正在运行的线程。当这两种情况发生时,我的程序应关闭: (1)。用户单击mainFrm中的“X”按钮(因此mainFrm.FormClosing被触发) (2)。在objectA中引发了一个事件(我们将其命名为“connectionClosed”) 因此,无论触发(1)或(2),此事件链始终应包括:C# 当用户单击“终止运行线程”;X";表单上的按钮,c#,multithreading,events,formclosing,C#,Multithreading,Events,Formclosing,假设我有一个名为mainFrm的表单和一个名为objectA的对象,该对象保存正在运行的线程。当这两种情况发生时,我的程序应关闭: (1)。用户单击mainFrm中的“X”按钮(因此mainFrm.FormClosing被触发) (2)。在objectA中引发了一个事件(我们将其命名为“connectionClosed”) 因此,无论触发(1)或(2),此事件链始终应包括: 底层线程中任何对象的终止。)我已经知道怎么做了 使用位于objectA中的代码优雅地终止它们) 当然,mainFrm要关门
...
this.FormClosed += objectA.kill;
objectA.connectionClosed +=closeForm;
...
private void closeForm(object sender, FormClosedEventArgs e)
{
try
{
this.Invoke(new MethodInvoker(delegate { this.Close(); }));
}
catch { }
}
在objectA的类中:
...
//connectionClosed is raised in different parts of objectA's threads code
connectionClosed += killClient;
...
public void killClient(object sender, FormClosedEventArgs e)
{
//event should go past this point just once
if (!_connectionClosed)
{
_connectionClosed = true;
try
{
... //close connection killing all threads
}
catch { }
}
}
根据(1)和(2)开头陈述的用例,这就是应该发生的事情(如果我没有弄错的话)
(1)。用户单击“X”按钮->表单关闭->表单关闭被引发->objectA.kill方法委托被执行->内部线程引发一些connectionClosed事件,这些事件将触发更多objectA.kill执行,但由于易失性bool\u connectionClosed,这不会造成任何损害(当然,因为有一个try/catch无论如何都会起作用,但对我来说,不要再执行这样的代码更有意义)->线程被objectA.kill->SUCCESS的唯一完整执行终止
(2).服务器关闭连接或网络错误->objectA的内部线程检测到连接错误并引发多个connectionClosed事件->不同的线程将尝试执行objectA.kill方法委托。->同时,在主窗体中执行closeForm,关闭窗体->这也会触发另一个objectA.kill执行(感谢this.FormClosed+=\u client.killClient;)->同样,这不会造成任何伤害,因为_connectionclosedvolatile bool将只允许一个线程实际执行代码(引发事件的第一个线程)->只有完全执行objectA.kill->SUCCESS才能正常终止线程
下一步应该是找到一种更方便的方法,这样connectionClosed可能只上升一次,我现在就用谷歌搜索它=)调用Close()有什么问题关于事件?如果您在FormClose上切换布尔值,则可以忽略下一个事件。如果您想在关闭窗体之前中断用户操作,则仅使用FormClosing。使用FormClosing可以阻止关闭论坛。如果某些数据未保存,并且您询问用户是否希望使用您关闭窗体,则通常使用此选项t保存,否则取消关闭
因此,不要使用FormClosing,使用FormClosing来清理实例。我不确定这是否能帮助您解决问题,但您应该参考以下代码。 这是一个使用线程对象来改变表单颜色的例子。当事件<代码>对象Objuta时,<代码>窗体<代码>自动关闭。DoMoOthOuts<代码>提高了20倍(<代码>如果(计数> 20):你可以考虑这个动作,就像你的事件连接被关闭了一样)。;或者您可以在线程运行时随时通过单击
Form1
的“X”按钮关闭Form1
public delegate void ObjectADoSomethingEventHandler(object sender, ObjectADoSomethingEventArgs e);
public class ObjectADoSomethingEventArgs : EventArgs
{
public int Value { get; private set; }
public ObjectADoSomethingEventArgs(int value)
{
Value = value;
}
}
public class ObjectA
{
public event ObjectADoSomethingEventHandler DoSomething;
protected void OnDoSomething(int value)
{
if (DoSomething != null)
DoSomething(this, new ObjectADoSomethingEventArgs(value));
}
public event EventHandler Closed;
protected void OnClosed()
{
if (Closed != null)
Closed(this, new EventArgs());
}
private BackgroundWorker _worker;
public ObjectA()
{
_worker = new BackgroundWorker();
_worker.DoWork += new DoWorkEventHandler(_objectA_DoWork);
_worker.ProgressChanged += new ProgressChangedEventHandler(_objectA_ProgressChanged);
_worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_objectA_RunWorkerCompleted);
_worker.WorkerReportsProgress = true;
_worker.WorkerSupportsCancellation = true;
}
public void Start()
{
_worker.RunWorkerAsync();
}
public void Kill()
{
if (_worker != null && _worker.IsBusy)
{
_worker.CancelAsync();
}
}
private void _objectA_DoWork(object sender, DoWorkEventArgs e)
{
int count = 0;
while (true)
{
_worker.ReportProgress(count);
count++;
if (count > 20)
{
return; // exit thread.
}
if (_worker.CancellationPending)
{
e.Cancel = true;
return; // Thread cancelled.
}
Thread.Sleep(500);
}
}
private void _objectA_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
OnDoSomething(e.ProgressPercentage);
}
private void _objectA_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
OnClosed();
}
}
public partial class Form1 : Form
{
private ObjectA _objectA;
public Form1()
{
InitializeComponent();
_objectA = new ObjectA();
_objectA.DoSomething += _objectA_DoSomething;
_objectA.Closed += _objectA_Closed;
_objectA.Start();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
_objectA.Kill();
}
private int _red = 128;
private int _green = 128;
private int _blue = 128;
void _objectA_DoSomething(object sender, ObjectADoSomethingEventArgs e)
{
_red += 15;
if (_red > 255) _red = 128;
_green -= 15;
if (_green < 0) _green = 128;
_blue += 15;
if (_blue > 255) _blue = 128;
this.BackColor = Color.FromArgb(_red, _green, _blue);
this.Text = string.Format("Count = {0}", e.Value);
}
void _objectA_Closed(object sender, EventArgs e)
{
Close();
}
}
public委托void ObjectADoSomethingEventHandler(对象发送方,ObjectADoSomethingEventArgs e);
公共类ObjectADoSomethingEventArgs:EventArgs
{
公共int值{get;private set;}
公共对象ADOSomethingEventArgs(int值)
{
价值=价值;
}
}
公共类对象
{
公共事件反对某些事情,甚至反对某些事情;
受保护的void OnDoSomething(int值)
{
if(DoSomething!=null)
DoSomething(此,新对象adosomethingeventargs(值));
}
公共事件处理程序关闭;
受保护的void OnClosed()
{
如果(关闭!=null)
已关闭(此为新的EventArgs());
}
私人背景工人;
公众反对a()
{
_worker=新的BackgroundWorker();
_worker.DoWork+=新的doworkenventhandler(\u objectA\u DoWork);
_worker.ProgressChanged+=新的ProgressChangedEventHandler(\u objectA\u ProgressChanged);
_worker.RunWorkerCompleted+=新的RunWorkerCompletedEventHandler(\u objectA\u RunWorkerCompleted);
_worker.WorkerReportsProgress=true;
_worker.worker支持扫描单元=true;
}
公开作废开始()
{
_worker.RunWorkerAsync();
}
公共空杀()
{
if(_-worker!=null&&u-worker.IsBusy)
{
_worker.CancelAsync();
}
}
私有void\u objectA\u DoWork(对象发送方,DoWorkEventArgs e)
{
整数计数=0;
while(true)
{
_工人。报告进度(计数);
计数++;
如果(计数>20)
{
return;//退出线程。
}
如果(_worker.CancellationPending)
{
e、 取消=真;
return;//线程已取消。
}
睡眠(500);
}
}
私有void\u objectA\u ProgressChanged(对象发送方,progresschangedventargs e)
{
OnDoSomething(如百分比);
}
私有void\u objectA\u RunWorkerCompleted(对象发送方,RunWorkerCompletedEventArgs e)
{
OnClosed();
}
}
公共部分类Form1:Form
{
私人反对a_反对a;
公共表格1()
{
初始化组件();
_objectA=新的objectA();
_objectA.DoSomething+=\u objectA\u DoSomething;
_objectA.Closed+=\u objectA\u Closed;
_objectA.Start();