【问题标题】:Mulitthreading problem with BeginInvoke, EndInvoke?BeginInvoke、EndInvoke 的多线程问题?
【发布时间】:2011-09-08 18:12:08
【问题描述】:

我有一个显示实时值的客户端应用程序。这些值是通过 DDE-Advise 提供的。这些实时值是数控机床的移动轴。因此,每分钟大约有 100 条建议通过此 DdeClientAdvise-Method 进入。
当应用程序获得许多 DDE 建议时,似乎突然间所有建议都丢失了。
我将问题简化为:

public class NcddeZugriff
{
  private DdeClient _ddeClient; //see http://ndde.codeplex.com/

  public NcDdeZugriff()
  {
    _ddeClient = new DdeClient("ncdde", "machineswitch");
    _ddeClient.Connect();
    _ddeClient.Advise += DdeClientAdvise;
  }

  private delegate void CallbackDelegate(object sender, DdeAdviseEventArgs e);    

  private void DdeClientAdvise(object sender, DdeAdviseEventArgs e)
  {
    CallbackDelegate callbackDelegate = DdeClientAdviseCallback;
    _logging.InfoFormat("Advise-Callback for {0}", e.Item);
    //LINE A : return;

    callbackDelegate.BeginInvoke(sender, e, callbackDelegate.EndInvoke, null);
  }

  private void DdeClientAdviseCallback(object sender, DdeAdviseEventArgs e)
  {
    _logging.InfoFormat("Asynchron for {0}", e.Item);
    //do some work with e.Text...
  }
}

如果我删除评论 LINE A,一切正常,没有任何建议丢失。正在记录所有建议。
如果我启用 BeginInvoke,一段时间后 DdeClientAdvise-Method 将不再被调用,不再有日志条目。

我在使用 BeginInvoke 和 EndInvoke 时做错了什么?

编辑:添加更多关于该类的信息。

【问题讨论】:

  • 您想要实现什么,通过将日志移出到单独的线程来加快建议处理?
  • DdeClientAdvise 函数在提供的代码栈顶,DdeClientAdvise 函数的调用者是谁?
  • 委托使用这样的代码收集垃圾的可能性很大。不可能从sn-p中看出哪一个。通过使用 GC.Collect() 提前强制 GC 来测试这个理论。通过将委托实例存储在类的字段中进行修复。
  • @Tigran:DdeClient-Class 订阅了 DDE-Server。方法DdeClientAdviseDdeClient-Class的Advise-Event的回调。
  • @sll:在单独的线程中调用了另一个线程,具体取决于 e.item。但这目前对问题没有影响。因为现在的代码就像上面一样。

标签: c# .net begininvoke


【解决方案1】:

您不必在 DdeClientAdviseCallback 中调用 EndInvoke 吗?

【讨论】:

    【解决方案2】:

    @Hans Passant 似乎是对的:委托正在收集垃圾。将委托存储在字段中似乎可以解决问题。
    虽然我改变了整个项目的设计。所以我不能肯定地说,这解决了这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多