如何使用 thread.abort()
How to use thread.abort()
如果用户需要,我只是尝试通过单击按钮停止进程来中止线程,而不是退出应用程序。
这是原始代码:
private void Abort_Click(object sender, EventArgs e)
{
// thread1.Abort();
}
/// Runs method 'Copy' in a new thread with passed arguments - on this way we separate it from UI thread otherwise it would freeze
private void backgroundCopy_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e )
{
List<object> genericlist = e.Argument as List<object>;
Thread thread1 = new Thread(() => Copy(genericlist[0].ToString(), genericlist[1].ToString()));
thread1.Start();
thread1.Join(); //Waiting for thread to finish
}
我尝试过的:
我尝试通过将 thread 字段移出方法来从按钮单击事件中获取 Abort() 线程,这样您就可以从按钮单击事件中获取访问权限,但它会抛出许多错误:
object sender;
System.ComponentModel.DoWorkEventArgs e;
List<object> genericlist = e.Argument as List<object>;
Thread thread1 = new Thread(() => Copy(genericlist[0].ToString(), genericlist[1].ToString()));
private void Abort_Click(object sender, EventArgs e)
{
thread1.Abort();
}
/// Runs method 'Copy' in a new thread with passed arguments - on this way we separate it from UI
thread otherwise it would freeze
private void backgroundCopy_DoWork( )
{
thread1.Start();
thread1.Join(); //Waiting for thread to finish
}
我就是这样做的,但出现错误:
under e and genericlist : a field initialize can not reference a non static field, method or property.
How to use thread.abort()
您不使用Thread.Abort()
,曾经,除非您正在紧急关闭整个应用程序域或过程。你永远不要这样做。我希望这很清楚。
您从不这样做的几个原因是:
- 有许多比中止异步工作流更好的控制异步工作流取消的方法。
- 中止线程并不能保证真正中止该线程。主动抵抗被中止的线程有办法无限期地延迟中止。它不可靠,所以不要使用它。
- 最重要的是:中止线程可以保证维护 CLR 用来管理线程的内部机制的正确性。 不保证保持程序的正确性!线程中止可能会导致您的程序不变量以有趣的方式被违反,这经常导致崩溃。 (练习:列出在构造带有终结器的对象期间发生线程中止的可能后果)
构建程序的正确方法是使用协作取消模式,并将异步工作表示为可以取消的任务。异步工作然后定期轮询令牌以查看它是否需要取消自身。
此外:如果异步工作不受处理器限制,那么正确的解决方案是不使用工作线程。相反,使用异步 IO 和 await
结果。你不会雇一个工人站在你的邮箱旁边,告诉你信件什么时候到达;同样,不要雇用工人站在那里等待 IO 任务完成。如果主线程未绑定 CPU,则将异步工作保留在主线程上,您的线程将在等待期间继续为用户请求提供服务。
I got an error a field initializer can not reference a non static field, method or property.
没错。字段初始值设定项不能以 任何 方式使用 this
,包括在 lambda 体内的隐式使用。这样做的原因是因为 字段初始化程序在构造函数主体运行之前运行 ,但它是构造函数的主体初始化 this
的字段。语言设计试图避免您在这里写下讨厌的错误。
您需要将初始化逻辑移动到构造函数中。
但更一般地说,如果您的程序要求您必须异步执行可由用户取消的高延迟 IO 绑定任务,那么您选择了错误的机制来正确和安全地实现该目标。
I am near the end of the project therefor I don't want to make a lot of changes.
我相信你不会。越早开始解决架构问题,您就会越早获得正确、安全的实施。
I have a deadline
这是管理问题,不是技术问题。我的建议是你向你的管理层解释情况。他们应该知道,选择是使用结构不正确且可能不稳定的程序来满足截止日期,或者延长截止日期并将程序重组为符合用户要求的有原则的、正确的、安全的程序。管理层应该有权就他们付钱给你的项目的状态做出明智的决定。
如果你必须使用线程,试试这个。否则,像 link 中那样尝试 cancelAsync:
https://www.wpf-tutorial.com/misc/cancelling-the-backgroundworker/
// We will set this true to notify the worker threads return.
private bool shouldAbort;
// when hitting submit set:
shouldAbort = false;
void MethodThatDoesWork()
{
//we should stop if required
if (shouldAbort)
{
state.Stop();
}
//code
}
我们必须确保在关闭表单时所有线程都已终止。
所以我们添加这些控件。
private void ItemsCopyer_FormClosing(object sender, FormClosingEventArgs e)
{
System.Diagnostics.Process.GetCurrentProcess().Kill();
}
private void btnAbort_Click(object sender, EventArgs e)
{
shouldAbort = true;
btnAbort.Enabled = false;
}
如果用户需要,我只是尝试通过单击按钮停止进程来中止线程,而不是退出应用程序。
这是原始代码:
private void Abort_Click(object sender, EventArgs e)
{
// thread1.Abort();
}
/// Runs method 'Copy' in a new thread with passed arguments - on this way we separate it from UI thread otherwise it would freeze
private void backgroundCopy_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e )
{
List<object> genericlist = e.Argument as List<object>;
Thread thread1 = new Thread(() => Copy(genericlist[0].ToString(), genericlist[1].ToString()));
thread1.Start();
thread1.Join(); //Waiting for thread to finish
}
我尝试过的:
我尝试通过将 thread 字段移出方法来从按钮单击事件中获取 Abort() 线程,这样您就可以从按钮单击事件中获取访问权限,但它会抛出许多错误:
object sender;
System.ComponentModel.DoWorkEventArgs e;
List<object> genericlist = e.Argument as List<object>;
Thread thread1 = new Thread(() => Copy(genericlist[0].ToString(), genericlist[1].ToString()));
private void Abort_Click(object sender, EventArgs e)
{
thread1.Abort();
}
/// Runs method 'Copy' in a new thread with passed arguments - on this way we separate it from UI
thread otherwise it would freeze
private void backgroundCopy_DoWork( )
{
thread1.Start();
thread1.Join(); //Waiting for thread to finish
}
我就是这样做的,但出现错误:
under e and genericlist : a field initialize can not reference a non static field, method or property.
How to use thread.abort()
您不使用Thread.Abort()
,曾经,除非您正在紧急关闭整个应用程序域或过程。你永远不要这样做。我希望这很清楚。
您从不这样做的几个原因是:
- 有许多比中止异步工作流更好的控制异步工作流取消的方法。
- 中止线程并不能保证真正中止该线程。主动抵抗被中止的线程有办法无限期地延迟中止。它不可靠,所以不要使用它。
- 最重要的是:中止线程可以保证维护 CLR 用来管理线程的内部机制的正确性。 不保证保持程序的正确性!线程中止可能会导致您的程序不变量以有趣的方式被违反,这经常导致崩溃。 (练习:列出在构造带有终结器的对象期间发生线程中止的可能后果)
构建程序的正确方法是使用协作取消模式,并将异步工作表示为可以取消的任务。异步工作然后定期轮询令牌以查看它是否需要取消自身。
此外:如果异步工作不受处理器限制,那么正确的解决方案是不使用工作线程。相反,使用异步 IO 和 await
结果。你不会雇一个工人站在你的邮箱旁边,告诉你信件什么时候到达;同样,不要雇用工人站在那里等待 IO 任务完成。如果主线程未绑定 CPU,则将异步工作保留在主线程上,您的线程将在等待期间继续为用户请求提供服务。
I got an error
a field initializer can not reference a non static field, method or property.
没错。字段初始值设定项不能以 任何 方式使用 this
,包括在 lambda 体内的隐式使用。这样做的原因是因为 字段初始化程序在构造函数主体运行之前运行 ,但它是构造函数的主体初始化 this
的字段。语言设计试图避免您在这里写下讨厌的错误。
您需要将初始化逻辑移动到构造函数中。
但更一般地说,如果您的程序要求您必须异步执行可由用户取消的高延迟 IO 绑定任务,那么您选择了错误的机制来正确和安全地实现该目标。
I am near the end of the project therefor I don't want to make a lot of changes.
我相信你不会。越早开始解决架构问题,您就会越早获得正确、安全的实施。
I have a deadline
这是管理问题,不是技术问题。我的建议是你向你的管理层解释情况。他们应该知道,选择是使用结构不正确且可能不稳定的程序来满足截止日期,或者延长截止日期并将程序重组为符合用户要求的有原则的、正确的、安全的程序。管理层应该有权就他们付钱给你的项目的状态做出明智的决定。
如果你必须使用线程,试试这个。否则,像 link 中那样尝试 cancelAsync: https://www.wpf-tutorial.com/misc/cancelling-the-backgroundworker/
// We will set this true to notify the worker threads return.
private bool shouldAbort;
// when hitting submit set:
shouldAbort = false;
void MethodThatDoesWork()
{
//we should stop if required
if (shouldAbort)
{
state.Stop();
}
//code
}
我们必须确保在关闭表单时所有线程都已终止。 所以我们添加这些控件。
private void ItemsCopyer_FormClosing(object sender, FormClosingEventArgs e)
{
System.Diagnostics.Process.GetCurrentProcess().Kill();
}
private void btnAbort_Click(object sender, EventArgs e)
{
shouldAbort = true;
btnAbort.Enabled = false;
}