作者zaqimon (dream)
看板C_Sharp
标题[问题] NDDE server/client写在同一支程式
时间Tue Apr 7 20:29:44 2020
我是C#初学还没什麽完整的概念
以前有写过C所以对程式还算有概念
我想用NDDE写一支类似DDE proxy的中介程式
所以我的程式同时需要当DdeServer跟DdeClient
把DdeServer.OnRequest直接丢给DdeClient.Request
但事情没那麽简单
DdeServer.OnRequest只要超过一个item就很容易exception
因为OnRequest会有reentrance的问题
我的DdeServer跟DdeClient已经使用不同DdeContext去new
这样DdeServer跟DdeClient才能跑在不同ManagedThreadId以避免冲突
但依然还是无法解决DdeServer.OnRequest reentrance的问题
只要去call了ddeClient.Request就会发生reentrance
换成Sleep就不会发生reentrance
以下是我的DdeServer.OnRequest程式码
请问有办法解决这个reentrace的问题吗?
有测试过lock锁不住
测试过semaphore直接deadlock
谢谢
protected override RequestResult OnRequest(DdeConversation conversation,
string item, int format)
{
if (format == 1)
{
byte[] re;
Console.WriteLine(">>>");
//Thread.Sleep(1000); // no reentrance
//re = ddeClient.Request(item, 1, 1000); // reentrance
re = (byte[])ddeClient.Context.Invoke(new Func<byte[]>(() =>
ddeClient.Request(item, 1, 1000)), null); // still reentrance
Console.WriteLine("<<<");
return new RequestResult(re);
}
return RequestResult.NotProcessed;
}
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 219.91.9.86 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_Sharp/M.1586262586.A.58D.html
※ 编辑: zaqimon (219.91.9.86 台湾), 04/07/2020 20:44:38
1F:推 Litfal: 你是要做到reentrace还是thread safe? 这里应该很少在讨论 04/07 22:31
2F:→ Litfal: reentrant的,你也应该不是遇到这个问题吧 04/07 22:31
当只有call Sleep()时Console log就很标准一进一出没有reentrance
>>>
<<<
>>>
<<<
>>>
<<<
...
但是当call了ddeClient.Request之後console log就变成
>>>
<<<
>>>
>>>
>>>
<<<
<<<
<<<
...
然後程式就很容易exception
就当在ddeClient.Request那一行
我想只要能解决reentrance的问题应该就不会当掉
※ 编辑: zaqimon (219.91.9.86 台湾), 04/08/2020 00:06:04
3F:→ ssccg: 不懂为什麽这种程式会想要做到一进一出? 除非预期只有一个 04/08 09:29
4F:→ ssccg: client,不然这样效能不会很差吗? 04/08 09:29
5F:→ ssccg: 通常只会想做thread safe,结果对就好执行顺序不重要吧 04/08 09:35
6F:→ ssccg: 至於会有exception那应该是要去研究到底为什麽有exception 04/08 09:35
7F:推 Litfal: 高阶语言不在意reentrance,你讲这个字还没什麽人懂。很多 04/08 19:39
8F:→ Litfal: 人连interrupt都不知道也能写一手好程式。你的问题应该是t 04/08 19:39
9F:→ Litfal: hread safe 04/08 19:39
10F:推 Litfal: 你用lock挡不住也不正常,先确定写法吧 04/08 19:43
因为每次OnRequest都是从DDEML callback过来的
都属於同一个thread
lock好像只能挡住不同thread的样子吧
所以档不住是正常的
https://github.com/anphonic/NDde/
应该说我不知道如何正确使用NDDE才能把DDE client/server写在同一支程式里面
大部分的使用情况不会需要把DDE client/server写在同一支程式
而且我的client/server之间还要呼叫到彼此的method
可能因此导致NDDE元件内部状态混乱吧
虽然NDDE有source code但我也看不懂
根据我简单测试
正常状态下DDE server的OnRequest不应该发生reentrance
但只要OnReuest内去呼叫到DdeClient.Request就会导致reentrance
然後就很容易exception
接下来我可能改用C# winform写写看
我好像有看到NDDE source code有建立隐藏视窗来处理window message
也许是console程式对thread或window message过敏吧
但NDDE给的sample程式又只是console而已
※ 编辑: zaqimon (219.91.9.86 台湾), 04/08/2020 23:30:31
11F:推 Litfal: console那行把thread id也印出来看看是不是真的在同一个执 04/09 14:25
12F:→ Litfal: 行绪下吧,是的话应该是client.Request又呼叫进入了server 04/09 14:25
13F:→ Litfal: .OnRequest,你要想想这是不是合理的行为 04/09 14:25
14F:→ Litfal: 我的话会用BlockQueue把server和client隔离 04/09 14:26
有测试过不论DdeServer跟DdeClient的ManagedThreadId是否相同
都会发生这个reentrance的问题
可能当初NDDE作者没有想到有人会需要把DdeServer跟DdeClient放在一起吧
※ 编辑: zaqimon (219.91.9.86 台湾), 04/10/2020 00:52:34