我需要一些在 C# 中使用线程的帮助
我正在用 C# 开发一个软件,该软件通过包装器使用 C++ .dll 文件中的静态函数。
问题是其中一些函数速度慢且不稳定,因此为了解决这个问题,我创建了一个执行它们的线程。 但是,当我从主线程中止该线程时,程序不允许我再次使用这些函数,即使我每次调用函数时都定义了一个新的线程实例。
有什么办法可以解决这个问题吗?
提前致谢。
PS:这是我的程序中的一些代码:
public partial class MainForm : Form, IMultiLanguage
{
//...
//This method is subscribed to the event of pressing the 'Abort' button
private void StopCurrentAnalisis()
{
try
{
this.analisisManagerController.AnalisisThread.Abort();
}
catch (Exception e){ }
finally
{
MessageBox.Show("Analisis has been cancelled by user", "Analisis Interrupted", MessageBoxButtons.OK, MessageBoxIcon.Stop);
CerrarNowLoadingForm();
}
}
//..
}
public class AnalisisManager: IAnalisisManagerController
{
//..
private Thread analisisThread;
public Thread AnalisisThread{get{return this.analisisThread;}}
public void MakePadrobAnalisis(TipoAnalisis tipoAnalisis,
Dictionary<string, Dictionary<int, double>> parametros)
{
object[] arregloParams = new object[]{tipoAnalisis,parametros};
analisisThread = new Thread(new ParameterizedThreadStart(MakeAnalisisInOtherThread));
analisisThread.Start(arregloParams);
}
private void MakeAnalisisInOtherThread(object o)
{
object[] arregloParams = o as object[];
TipoAnalisis tipoAnalisis = (TipoAnalisis) arregloParams[0];
Dictionary<string, Dictionary<int, double>> parametros = arregloParams[1] as Dictionary<string, Dictionary<int, double>>;
//This launches an event telling the GUI the unstable analisis has started.
//The method that makes the 'Abort' button to appear on the GUI is subscribed to this event
StartAnalisis();
//The Thread executes DLL functions according to tipoAnalisis, for example:
case InvKinematicsMinTorque:
{
WrapperPadirob.InverseKinematicsMinTorqueConfigAnalisis();
break;
}
//..
}
}
I´m developing a software in C# that uses static functions from a C++ .dll file through a Wrapper.
The problem is that some of these functions are slow and unstable, so in order to solve this I created a Thread that executes them. However, when I abort that thread from the main thread, the program isn´t letting me use those functions again, even though I define a new instance of the thread every time I call a function.
Is there any way I can fix this?
Thanks in advance.
PS: Here is some code from my program:
public partial class MainForm : Form, IMultiLanguage
{
//...
//This method is subscribed to the event of pressing the 'Abort' button
private void StopCurrentAnalisis()
{
try
{
this.analisisManagerController.AnalisisThread.Abort();
}
catch (Exception e){ }
finally
{
MessageBox.Show("Analisis has been cancelled by user", "Analisis Interrupted", MessageBoxButtons.OK, MessageBoxIcon.Stop);
CerrarNowLoadingForm();
}
}
//..
}
public class AnalisisManager: IAnalisisManagerController
{
//..
private Thread analisisThread;
public Thread AnalisisThread{get{return this.analisisThread;}}
public void MakePadrobAnalisis(TipoAnalisis tipoAnalisis,
Dictionary<string, Dictionary<int, double>> parametros)
{
object[] arregloParams = new object[]{tipoAnalisis,parametros};
analisisThread = new Thread(new ParameterizedThreadStart(MakeAnalisisInOtherThread));
analisisThread.Start(arregloParams);
}
private void MakeAnalisisInOtherThread(object o)
{
object[] arregloParams = o as object[];
TipoAnalisis tipoAnalisis = (TipoAnalisis) arregloParams[0];
Dictionary<string, Dictionary<int, double>> parametros = arregloParams[1] as Dictionary<string, Dictionary<int, double>>;
//This launches an event telling the GUI the unstable analisis has started.
//The method that makes the 'Abort' button to appear on the GUI is subscribed to this event
StartAnalisis();
//The Thread executes DLL functions according to tipoAnalisis, for example:
case InvKinematicsMinTorque:
{
WrapperPadirob.InverseKinematicsMinTorqueConfigAnalisis();
break;
}
//..
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
那是你的问题。 您不应该使用 Thread.Abort。 查看这篇文章中的“非邪恶取消” 寻求更好的方法。 从那里 ...
另外,在此SO线程中对此进行了很好的讨论。
根据评论:
您拥有这个线程……
它执行一个指向……的委托
,您也拥有该方法。 如果 C++ 接口没有合理的 .StopAnalysis 方法(或类似的方法),则必须等到分析完成,然后按照文章中的讨论轮询主线程。 炸毁你的线程来停止分析并不是正确的做法。
That's your problem. You should not be using Thread.Abort. Check out "Non-Evil Cancellation" in this article for a better approach. From there ...
Also, very good discussion of this in this SO thread.
Per comment:
You own this thread ...
... it executes a delegate pointing to ...
... you also own that method. If the C++ interface does not have a reasonable .StopAnalysis method (or something similar), you must wait until the analysis is done and then poll the main thread as discussed in the articles. Blowing up your thread to stop the analysis is not the right thing to do.
顺便说一句,你的 C++ dll 是为在多线程中工作而编写的吗? 它可能使用仅在仅与一个线程一起使用时才有效的技术。 在多个线程中运行它,可能会发生非常令人讨厌的事情,例如不同的用户访问彼此的数据,或者代码覆盖 C 运行时库堆。
BTW, is your C++ dll written to work in multiple threads? It's possible that it uses techniques that only work when it's being used with only one thread. Run it in multiple threads, and very nasty things could happen, like different users accessing each others data, or the code overwriting the C runtime library heap.
与其一直创建和终止线程,不如创建一个运行如下代码的线程:
然后,您可以
设置
自动重置事件,该事件会将线程从挂起状态唤醒并为其提供服务一个请求。这还有一个额外的好处,即所有调用都将从单个线程对 DLL 进行。
Rather than creating and killing threads all the time, it's better to create one thread which runs code like this:
Then, you can
Set
the auto-reset event which will wake the thread from suspend and have it service one request.This has the additional benefit that all calls will be made to the DLL from a single thread.
很抱歉这么说,但是您当前的设计是有缺陷的,如果您在线程运行某些任意非托管代码时中止线程,则您将面临损坏应用程序的风险。 句柄可能泄漏,内存可能泄漏,可能会导致各种极其难以调试的并发问题。
为了解决此类问题,我建议:
Sorry to say this, but your current design is flawed, if you abort a thread while its running some arbitrary unmanaged code you are risking corrupting your application. Handles can leak, memory can leak, you can cause all sorts of incredibly hard to debug concurrency issues.
To solve this kind of problem I would recommend:
允许方法调用因任何原因超时的一种巧妙方法是使用委托调用。
A slick way to allow a method call to timeout for whatever reason is to use a delegate call.