我是WCF的新手,只是学习如何让客户端使用MSMQ与主机(在控制台应用程序中)进行通信。
我希望能够从客户端向主机发送消息,让主机立即接收消息,或者如果主机停止,则在重新启动时继续从中断。
我已经有了这个工作,但我发现当我重新启动队列中有10条消息的主机时,消息不按队列顺序处理。我假设有一些多线程正在使它们出现故障。我希望能够限制WCF服务一次处理一条消息以阻止这种情况发生(除非有更好的解决方案)。
对于我即将处理的系统来说,MSMQ消息是按顺序处理而不是并行处理是必不可少的。
我的服务合同的代码是:
[ServiceContract(Namespace = "http://www.heronfoods.com/DemoService")]
public interface IDemoService
{
[OperationContract(IsOneWay = true)]
void SendMessage(string message);
}
对于服务合同的实施,我得到了这个。 (控制台输出是因为这是一个供我学习的演示应用程序):
public class DemoService : IDemoService
{
public void SendMessage(string message)
{
Console.WriteLine("{0} : {1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), message);
}
}
我的主机应用程序是一个控制台应用程序,其代码如下:
class Program
{
static void Main(string[] args)
{
Console.Title = "WCF Host";
using (var host = new ServiceHost(typeof(Library.DemoService)))
{
var endpoint = new ServiceEndpoint(
ContractDescription.GetContract(typeof(Library.IDemoService)),
new NetMsmqBinding(NetMsmqSecurityMode.None),
new EndpointAddress("net.msmq://localhost/private/test"));
host.AddServiceEndpoint(endpoint);
host.Open();
Console.WriteLine("Host Active");
Console.ReadLine();
}
}
}
客户同样简单:
class Program
{
static void Main(string[] args)
{
Console.Title = "WCF Client";
IDemoService proxy = ChannelFactory<IDemoService>.CreateChannel(
new NetMsmqBinding(NetMsmqSecurityMode.None),
new EndpointAddress("net.msmq://localhost/private/test")
);
do
{
string msg = Console.ReadLine();
if (msg=="")
break;
else
proxy.SendMessage(msg);
} while (true);
}
}
答案 0 :(得分:0)
我假设你的队列不是交易的。
虽然我不确定是否有办法将netMsmqBinding限制为单个线程,但您不需要应用此限制。
为了保证订购的交付,您只需要使您的队列成为事务性的,然后将exactlyOnce
属性应用于netMsmqBinding配置。
参见示例here。