如何中止已经运行的特定线程? [英] How do I abort a specific thread that is already running?

查看:63
本文介绍了如何中止已经运行的特定线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对线程有问题.我想拥有一个processThread,我可以使其尽可能多地重用,并且还具有停止已经运行的线程,处置正在运行的线程并在同一线程中启动一个新线程的功能!

我仅使用线程和任务进行了很多尝试,但无法按我的要求进行工作.

我想要这样做的原因是要模拟来自文本框字段的RealTime计算,在那里该线程将在KeyUp上调用.当用户继续在同一文本框中键入内容时,应重新启动从KeyUp调用的线程.这与包含一些字符的特殊验证相关,因此必须重新启动/中止该过程.

在这种方法中,我想使用Thread.Sleep(1500)只是为了确保用户已停止键入.
代码如下,该小代码给出了底部显示的错误:

I have a problem with threading. I want to have a processThread that I can reuse as many times as possible and also gives the ability of stopping an already running thread, dispose the running thread and start a new one in the same thread!

I have tried alot with just Thread and Task but can''t get it work as I want.

The reason I want this is to simulate a RealTime calculation from a textbox field, there the thread will be called on KeyUp. And when the user continues to type in the same textbox the Thread that was called from the KeyUp should be restarted. This is connected to a special validation which includes some characters and therefore the process has to be restarted/aborted.

In this method I want to use Thread.Sleep(1500) just to make sure that the user has stopped typing.
The code is as following and this little code gives the error shown in the bottom:

if(processThread.IsAlive)
   {
       processThread.Abort();
   }



代码:



Code:

private Thread processThread;

private void incomeTBX1FP_KeyUp(object sender, KeyEventArgs e)
{
    bool processSucceed = false;
    if(processThread.IsAlive)
    {
        processThread.Abort();
    }

    Thread.Sleep(1500);
    processThread = new Thread((ThreadStart)delegate
        {
            ProcessValidationAndMemory(incomeTBX1FP.Text, income1LblFP.Text, 501, 1, out processSucceed);
            if (!processSucceed)
            {
                MessageBox.Show(incomeTBX1FP.Text + "innehåller ett felaktigt värde", "Ett fel har uppstått", MessageBoxButtons.OK, MessageBoxIcon.Error);
                incomeTBX1FP.Focus();
                incomeTBX1FP.SelectAll();
            }
        });
    processThread.Name = "InputThread";
    processThread.Start();

}


private void ProcessValidationAndMemory(string inputString, string inputLabel, short labelIndex, short incomeIndex, out bool processSucceed)
{
    double moneyValue;
    if (InputUtility.GetIncome(out moneyValue, inputString))
    {
        incomeArray[incomeIndex] = moneyValue;
        allLabels[labelIndex] = inputLabel;
        MessageBox.Show(incomeArray[incomeIndex].ToString() + " kr " + allLabels[labelIndex].ToString(), "TEST", MessageBoxButtons.OK);
        processSucceed = true;
    }
    else
    {
        processSucceed = false;
    }
}


错误消息:

未处理System.NullReferenceException
Message =对象引用未设置为对象的实例.
来源=我的经济精简版
StackTrace:
在C:\ Users \ Michael \ documents \ visual studio 2010 \ Projects \ My Economy Lite \ My Economy Lite \ MainWindows.cs:line 39中的My_Economy_Lite.MainWindows.incomeTBX1FP_KeyUp(Object sender,KeyEventArgs e)中 在System.Windows.Forms.Control.OnKeyUp(KeyEventArgs e)
在System.Windows.Forms.Control.ProcessKeyEventArgs(Message& m)
在System.Windows.Forms.Control.ProcessKeyMessage(Message& m)中
在System.Windows.Forms.Control.WndProc(Message& m)中
在System.Windows.Forms.TextBoxBase.WndProc(Message& m)中
在System.Windows.Forms.TextBox.WndProc(Message& m)
在System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
在System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
在System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam)
在System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)中
在System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID,Int32原因,Int32 pvLoopData)
在System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32原因,ApplicationContext上下文)中
在System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32原因,ApplicationContext上下文)
在System.Windows.Forms.Application.Run(Form mainForm)处
在C:\ Users \ Michael \ documents \ visual studio 2010 \ Projects \ My Economy Lite \ My Economy Lite \ Program.cs:line 18中的My_Economy_Lite.Program.Main() 在System.AppDomain._nExecuteAssembly(RuntimeAssembly程序集,String [] args)中
at System.AppDomain.ExecuteAssembly(String assemblyFile,Evidence assemblySecurity,String [] args)
在Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
在System.Threading.ThreadHelper.ThreadStart_Context(对象状态)处
在System.Threading.ExecutionContext.Run(ExecutionContext执行上下文,ContextCallback回调,对象状态,布尔值ignoreSyncCtx)处
在System.Threading.ExecutionContext.Run(ExecutionContext执行上下文,ContextCallback回调,对象状态)处
在System.Threading.ThreadHelper.ThreadStart()处
InnerException:


Error Message:

System.NullReferenceException was unhandled
Message=Object reference not set to an instance of an object.
Source=My Economy Lite
StackTrace:
at My_Economy_Lite.MainWindows.incomeTBX1FP_KeyUp(Object sender, KeyEventArgs e) in C:\Users\Michael\documents\visual studio 2010\Projects\My Economy Lite\My Economy Lite\MainWindows.cs:line 39
at System.Windows.Forms.Control.OnKeyUp(KeyEventArgs e)
at System.Windows.Forms.Control.ProcessKeyEventArgs(Message& m)
at System.Windows.Forms.Control.ProcessKeyMessage(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.TextBoxBase.WndProc(Message& m)
at System.Windows.Forms.TextBox.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at My_Economy_Lite.Program.Main() in C:\Users\Michael\documents\visual studio 2010\Projects\My Economy Lite\My Economy Lite\Program.cs:line 18
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:

推荐答案

除了Piccadilly的答案,您的代码还有几个问题:

1-不建议呼叫Abort.这不是停止线程的干净方法.此外,您还需要处理正在运行的线程引发的异常.
相反,我会建议使用BackgroundWorker,并使用CancelAsync方法(然后您需要从线程函数中定期检查CancellationPending属性).
使用BackgroundWorkers的另一个重要优点是您可以根据需要多次使用它.

2-您正在从线程( Text 属性, Focus 方法等)访问UI对象.不要那样做看看MSDN上的InvokeRequired属性,InvokeBeginInvoke方法,以了解更多信息.
而是将参数发送到您的线程函数.

但是主要的问题是:您是否真的需要一个线程来执行您想做的事情?您不能在事件处理程序中执行所有操作吗?
In addition to Piccadilly''s answer, there are several problems with your code:

1- Calling Abort is not recommanded. It is not a clean way to stop a thread. Besides, you need to handle the exception that will be raised from the running thread.
Instead I would recommand to use a BackgroundWorker, and use CancelAsync method (you will then need to check regularly the CancellationPending property from within the thread function).
One other important advantage about using a BackgroundWorkers is you can re-use it as many times as you want.

2- You are accessing UI objects from the thread (Text property, Focus method, and so on). Don''t do that. Have a look to the InvokeRequired property, Invoke and BeginInvoke methods from MSDN to know more about that.
Instead, send arguments to your thread function.

But the main question is: do you really need a thread to do what you want to do? Can''t you do all that in the event handler?


尝试一下:

Try this :

if(processThread!=null && processThread.IsAlive)
   {
       processThread.Abort();
   }



在中止线程之前也要停止线程



also stop thread before abort it


这篇关于如何中止已经运行的特定线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆