我正在尝试从现有的慢速同步WCF服务功能实现异步反馈。所以我按照MSDN示例熟悉: https://msdn.microsoft.com/en-us/library/ms731177(v=vs.90).aspx
我重用了示例中的CompletedAsyncResult。主机WCF服务:
[ServiceContract]
public interface IService
{
[OperationContract]
string SlowHelloWorld(string msg);
[OperationContract(AsyncPattern = true)]
IAsyncResult BeginFeedback(string msg, AsyncCallback callback, object asynState);
string EndFeedback(IAsyncResult result);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class Service : IService
{
public string SlowHelloWorld(string msg)
{
Console.WriteLine("SlowHelloWorld called with: \"{0}\"", msg);
Thread.Sleep(5000);
return "Hello world " + msg;
}
public IAsyncResult BeginFeedback(string msg, AsyncCallback callback, object asynState)
{
Console.WriteLine("BeginServiceAsyncMethod called with: \"{0}\"", msg);
return new CompletedAsyncResult<string>(msg);
}
public string EndFeedback(IAsyncResult r)
{
CompletedAsyncResult<string> result = r as CompletedAsyncResult<string>;
Console.WriteLine("EndServiceAsyncMethod called with: \"{0}\"", result.Data);
Thread.Sleep(1000);
return result.Data;
}
}
创建主持人:
internal class Program
{
private static void Main(string[] args)
{
Uri addr = new Uri("net.tcp://localhost:4588");
NetTcpBinding binding = new NetTcpBinding();
binding.Security.Mode = SecurityMode.None;
Service service = new Service();
var host = new ServiceHost(service, addr);
host.AddServiceEndpoint(typeof(IService), binding, "Message");
host.Open();
Console.ReadKey();
}
}
客户:
private static void Main(string[] args)
{
var binding = new NetTcpBinding();
binding.Security.Mode = SecurityMode.None;
var endpoint = new EndpointAddress("net.tcp://localhost:4588/Message");
var channelFactory = new ChannelFactory<IService>(binding, endpoint);
IService client = null;
try
{
Mutex mutex = new Mutex();
var numberOfThreads = 10;
var message = "I am Client";
client = channelFactory.CreateChannel();
int globalValue = 0;
for (int i = 0; i < numberOfThreads; i++)
{
var thread = new Thread(() =>
{
// increment counter safely
mutex.WaitOne();
var threadValue = globalValue;
globalValue++;
mutex.ReleaseMutex();
// wait for slow hello world to start before calling async method
Thread.Sleep(500);
var res = client.BeginFeedback(
threadValue.ToString(),
delegate(IAsyncResult r)
{
var result = client.EndFeedback(r);
Console.WriteLine(result);
},
null);
});
thread.Start();
}
Console.WriteLine(client.SlowHelloWorld(message));
Console.ReadKey();
((ICommunicationObject)client).Close();
}
catch
{
if (client != null)
{
((ICommunicationObject)client).Abort();
}
}
}
忽略退货订单无法保证的事实。
这个解决方案给了我错误的结果,因为慢速方法完成然后线程可以完成他们的工作ala:
Hello world I am Client
1
0
3
6
2
9
8
4
7
5
接下来我发现了一些提示,我可能错误地调用了客户端函数: https://stackoverflow.com/questions/22590239/calling-async-methods-from-a-wcf-service/22591516#22591516 http://geekswithblogs.net/MarkPearl/archive/2011/10/12/async-using-the-old-async-begin--end-pattern.aspx https://stackoverflow.com/questions/448487/is-there-a-way-to-get-error-feedback-on-asynchronous-wcf-calls
所以我继续试图以异步方式调用主机方法,希望如此。
public delegate void MethodInvoker();
并将Thread方法改为:
client.BeginFeedback(
threadValue.ToString(),
delegate(IAsyncResult r)
{
var invoker = new MethodInvoker(delegate()
{
var result = client.EndFeedback(r);
Console.WriteLine(result);
});
invoker.Invoke();
},
null);
结果相同。
尝试异步调用慢速方法(希望如此):
public delegate string AsyncMethodCaller(string message);
var caller = new AsyncMethodCaller(client.SlowHelloWorld);
caller.BeginInvoke(
message,
new AsyncCallback(delegate(IAsyncResult result)
{
AsyncResult beginResult = (AsyncResult)result;
AsyncMethodCaller endCaller = (AsyncMethodCaller)beginResult.AsyncDelegate;
var endResult = endCaller.EndInvoke(beginResult);
Console.WriteLine(endResult);
}),
null);
仍然没有运气。这些似乎暗示ConcurrencyMode在主机端必须是Multiple。但没有区别。 https://stackoverflow.com/questions/17080037/async-wcf-self-hosted-service https://stackoverflow.com/questions/11264825/accessing-persession-service-simultaneously-in-wcf-using-c-sharp
这个似乎是我想要的,向现有的同步接口添加异步功能,但我不能使用await,async和Task作为.Net 3.5 https://stackoverflow.com/questions/27882501/how-to-add-async-support-to-a-net-4-5-wcf-service-so-it-doesnt-disrupt-existin
所以问题: 我缺少什么/我不了解异步WCF通信?
我调用的所有服务方法是否也必须遵循异步模式?包括长时间运行的方法。