gpt4 book ai didi

c# - 异步 WCF : wait for another call

转载 作者:行者123 更新时间:2023-11-30 22:37:40 26 4
gpt4 key购买 nike

我们的框架中有一个旧的 Silverlight UserControl + WCF 组件,我们想增加此功能的可重用性。该组件应该使用默认情况下的基本功能,但我们想在当前项目的基础上扩展它(不修改原来的,这样更多的控件可以出现在具有不同功能的完整系统)。

所以我们制定了一个计划,除了一件事,一切看起来都很棒。这是一个简短的总结:

Silverlight UserControl 可以通过 UI 中的 ContentPresenter 和客户端逻辑中的 ViewModel 继承、事件和消息传递进行扩展和操作。

后端业务逻辑可以通过模块加载来操作。

我想这会没问题。例如,您可以使用覆盖的 ViewModel 属性从 UI 中禁用/删除字段,并且在后端您可以避免使用自定义模块进行某些操作。

有趣的部分是当您通过 ContentPresenter 添加新字段时。好的,您将新属性添加到继承的 ViewModel,然后您可以绑定(bind)到它们。您有其他数据。当您保存基础数据时,您知道它已经成功,然后您可以开始保存您的附加数据(附加数据可以是任何东西,例如在后端的不同表中)。很好,我们扩展了我们的 UserControl 和后端逻辑,原始 userControl 仍然不知道关于我们的扩展的任何事情。

但是我们失去了交易。例如,我们可以保存基础数据,但额外的数据保存会抛出异常,我们有更新的基础数据,但附加表中没有任何内容。我们真的不希望有这种可能性,所以我想出了这个主意:

一个WCF调用应该在后端等待另一个,如果两个都到达了,我们就可以开始它们之间的跨线程通信,当然,我们可以在同一个事务中处理基础数据和附加数据,而基础组件仍然对另一个一无所知(它只是提供了一个功能来用它做某事,但它不知道谁来做)。

我做了一个非常简化的概念验证解决方案,这是输出:

1 send begins

Press return to send the second piece

2 send begins

2 send completed, returned: 1

1 send completed, returned: 2

服务

namespace MyService
{
[ServiceContract]
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public class Service1
{

protected bool _sameArrived;

protected Piece _same;

[OperationContract]
public Piece SendPiece(Piece piece)
{
_sameArrived = false;
Mediator.Instance.WaitFor(piece, sameArrived);

while (!_sameArrived)
{
Thread.Sleep(100);
}

return _same;
}

protected void sameArrived(Piece piece)
{
_same = piece;
_sameArrived = true;
}
}
}

block (实体)

namespace MyService
{
[DataContract]
public class Piece
{
[DataMember]
public long ID { get; set; }

[DataMember]
public string SameIdentifier { get; set; }
}
}

中介者

namespace MyService
{
public sealed class Mediator
{
private static Mediator _instance;

private static object syncRoot = new Object();

private List<Tuple<Piece, Action<Piece>>> _waitsFor;

private Mediator()
{
_waitsFor = new List<Tuple<Piece, Action<Piece>>>();
}

public static Mediator Instance
{
get
{
if (_instance == null)
{
lock (syncRoot)
{
_instance = new Mediator();
}
}

return _instance;
}
}

public void WaitFor(Piece piece, Action<Piece> callback)
{
lock (_waitsFor)
{
var waiter = _waitsFor.Where(i => i.Item1.SameIdentifier == piece.SameIdentifier).FirstOrDefault();

if (waiter != null)
{
_waitsFor.Remove(waiter);
waiter.Item2(piece);
callback(waiter.Item1);
}
else
{
_waitsFor.Add(new Tuple<Piece, Action<Piece>>(piece, callback));
}
}
}
}
}

客户端代码

    namespace MyClient
{
class Program
{
static void Main(string[] args)
{
Client c1 = new Client(new Piece()
{
ID = 1,
SameIdentifier = "customIdentifier"
});

Client c2 = new Client(new Piece()
{
ID = 2,
SameIdentifier = "customIdentifier"
});

c1.SendPiece();
Console.WriteLine("Press return to send the second piece");
Console.ReadLine();
c2.SendPiece();
Console.ReadLine();
}
}

class Client
{
protected Piece _piece;

protected Service1Client _service;

public Client(Piece piece)
{
_piece = piece;
_service = new Service1Client();
}

public void SendPiece()
{
Console.WriteLine("{0} send begins", _piece.ID);
_service.BeginSendPiece(_piece, new AsyncCallback(sendPieceCallback), null);
}

protected void sendPieceCallback(IAsyncResult result)
{
Piece returnedPiece = _service.EndSendPiece(result);
Console.WriteLine("{0} send completed, returned: {1}", _piece.ID, returnedPiece.ID);
}
}
}

那么等待另一个 WCF 调用(它可能会被调用也可能不会被调用,所以在真实的例子中会更复杂),并与跨线程一起处理它们是个好主意吗沟通? 还是不行,我应该寻找其他解决方案吗?

提前致谢

黑色

最佳答案

如果您想在不更改任何现有代码的情况下扩展您的应用程序,您可以使用 MEF,即 Microsoft Extensibility Framework。

要将 MEF 与 silverlight 结合使用,请参阅:http://development-guides.silverbaylabs.org/Video/Silverlight-MEF

我不会等待来自 Silverlight 的 2 个 WCF 调用,原因如下:

  • 您正在使您的代码更加复杂且难以维护
  • 您正在存储业务知识,即两个服务应该在客户端一起调用

我会调用一个聚合了两个服务的服务。

关于c# - 异步 WCF : wait for another call,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6396666/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com