我需要一些帮助在C#中使用Threads

时间:2009-07-04 00:23:45

标签: c# multithreading process

我在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;
       }
       //..
   }
}

5 个答案:

答案 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)

BTW,你的C ++ dll是用多线程编写的吗?它可能使用仅在与一个线程一起使用时才有效的技术。在多个线程中运行它,并且可能发生非常讨厌的事情,例如不同的用户访问彼此的数据,或者代码覆盖C运行时库堆。

答案 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#应用​​程序中消费并且是   寻找最好的消费方式   此

很抱歉这样说,但是你当前的设计是有缺陷的,如果你在运行一些任意非托管代码时中止一个线程,你就有可能破坏你的应用程序。 句柄可能泄漏内存可能泄漏,您可能导致各种非常难以调试并发问题

为了解决这类问题,我建议:

  • 最佳解决方案:修复非托管dll。
  • 第二个最佳解决方案:运行一个单独的流程,其唯一的责任是与问题dll交互,如果填充了内容,则终止流程然后再次启动它。让您的主应用程序使用远程处理或WCF与该流程进行通信

答案 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 ();