我在C#中开发一个软件,它通过Wrapper使用C ++ .dll文件中的静态函数。
问题是这些函数中的一些是缓慢且不稳定的,所以为了解决这个问题,我创建了一个执行它们的Thread。但是,当我从主线程中止该线程时,程序不允许我再次使用这些函数,即使我每次调用函数时都定义了一个新的线程实例。
有什么方法可以解决这个问题吗?
提前致谢。
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;
}
//..
}
}
答案 0 :(得分:5)
但是,当我中止该线程时 来自主线程
那是你的问题。你不应该使用Thread.Abort。查看this article中的“非邪恶取消”以获得更好的方法。从那里......
我总是推荐的方法是 死得很简单。有一个挥发性的bool 您可以看到的字段 工作线程和您的UI线程。如果 用户单击取消,设置此标志。 同时,在你的工作线程上,测试一下 不时的旗帜。如果你看到 它得到了设定,停止你正在做的事情。
此外,在SO thread中对此进行了非常好的讨论。
每条评论:
你拥有这个帖子......
Thread AnalisisThread{get{return this.analisisThread;}}
...它执行指向...
的委托private void MakeAnalisisInOtherThread(object o)
...你也拥有那种方法。如果C ++接口没有合理的.StopAnalysis方法(或类似的东西),则必须等到分析完成后再按照文章中的讨论轮询主线程。炸毁你的线程以停止分析是不对的。
答案 1 :(得分:1)
答案 2 :(得分:1)
不是一直创建和终止线程,最好创建一个运行如下代码的线程:
private void Worker()
{
while (m_bRunning)
{
m_autoResetEvent.WaitOne();
DoWork(); // eg. call all required functions, maybe by popping requests off a queue
}
}
然后,您可以Set
自动重置事件,该事件将唤醒线程暂停并让它为一个请求提供服务。
这具有额外的好处,即将从单个线程对DLL进行所有调用。
答案 3 :(得分:1)
回顾一下:你有一些非托管代码 这是不稳定的,你需要 从你的C#应用程序中消费并且是 寻找最好的消费方式 此
很抱歉这样说,但是你当前的设计是有缺陷的,如果你在运行一些任意非托管代码时中止一个线程,你就有可能破坏你的应用程序。 句柄可能泄漏,内存可能泄漏,您可能导致各种非常难以调试并发问题。
为了解决这类问题,我建议:
答案 4 :(得分:0)
允许方法调用因任何原因超时的灵巧方法是使用委托调用。
[DllImport ("mydll.dll")]
private extern void method_call ();
private void thing_1 ()
{
dll_method_call failing_method;
IAsycResult method_result;
Int32 method_timeout;
method_timeout = 15000;
failing_method = method_call;
method_result = failing_method.BeginInvoke (null, null);
if (method_result.AsyncWaitHandle.WaitOne (method_timeout))
{
method_result.EndInvoke ();
//Success
}
else
{
//Failure
}
}
private delegate void dll_method_call ();