2011-07-15 50 views
2

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

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... 
    } 
} 

如果我删除注释行A,一切正常,没有提醒迷路了。所有的建议都被记录下来。
如果我启用BeginInvoke,一段时间后DdeClientAdvise-方法不再被调用,不再有日志条目。

我在做什么错误的BeginInvoke,EndInvoke?

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

+0

你试图实现什么,加快建议通过移出日志到单独的线程处理? – sll

+0

DdeClientAdvise函数位于提供的代码堆栈的顶部,谁是DdeClientAdvise函数的调用者? – Tigran

+0

赔率很好,代表正在用这样的代码收集垃圾。无法看到片段中的哪一个。通过使用GC.Collect()来尽早强制GC来测试该理论。通过将委托实例存储在类的字段中进行修复。 –

回答

0

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

0

你不需要在DdeClientAdviseCallback中调用EndInvoke吗?