Mar*_*tin 21 c# wcf asynchronous task-parallel-library
我试图使WCF REST方法完全异步(我不想阻止任何地方).基本上我有一个简单的服务,有3层:服务,业务逻辑和数据访问层.数据访问层正在访问数据库,可能需要几秒钟才能从该方法获得响应.
我不太清楚如何链接所有这些方法的工作.有人可以帮我完成我试图在下面写的样本吗?我不太了解WCF使用的模式,我没有找到关于这个主题的很多文档.
有人可以帮我完成以下示例吗?此外,如何测量服务能够处理比典型同步实现更多的负载?
using System;
using System.Collections.Generic;
using System.Runtime.Remoting.Messaging;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Threading.Tasks;
namespace WcfRestService1
{
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode =
AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class Service1
{
private BusinessLogic bll = new BusinessLogic();
// Synchronous version
[WebGet(UriTemplate = "/sync")]
public string GetSamples()
{
return bll.ComputeData();
}
// Asynchronous version - Begin
[WebGet(UriTemplate = "/async")]
[OperationContract(AsyncPattern = true)]
public IAsyncResult BeginGetSampleAsync(AsyncCallback callback,
object state)
{
Task<string> t = bll.ComputeDataAsync();
// What am I suppose to return here
// return t.AsyncState; ???
}
// Asynchronous version - End
public List<SampleItem> EndGetSampleAsync(IAsyncResult result)
{
// How do I handle the callback here?
}
}
public class BusinessLogic
{
public Task<string> ComputeDataAsync()
{
DataAccessLayer dal = new DataAccessLayer();
return dal.GetData();
}
public string ComputeData()
{
Task<string> t = this.ComputeDataAsync();
// I am blocking... Waiting for the data
t.Wait();
return t.Result;
}
}
public class DataAccessLayer
{
public Task<string> GetData()
{
// Read data from disk or network or db
}
}
}
Run Code Online (Sandbox Code Playgroud)
JMa*_*sch 11
这是一个例子.我得到了以下帖子的帮助:
编辑:添加了异步客户端的示例
使用TPL实现经典异步模式
http://pfelix.wordpress.com/2008/06/27/wcf-and-the-asyncpattern-property-part-1/
http://pfelix.wordpress.com/2008/06/ 28/WCF和最asyncpattern部分-2 /
这是一个小小的无所事事服务:
namespace WcfAsyncTest
{
[ServiceContract]
public interface IAsyncTest
{
[OperationContract(AsyncPattern=true)]
IAsyncResult BeginOperation(AsyncCallback callback, object state);
string EndOperation(IAsyncResult ar);
}
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class Service1 : IAsyncTest
{
public IAsyncResult BeginOperation(AsyncCallback callback, object state)
{
Task result = Task.Factory.StartNew((x) =>
{
// spin to simulate some work
var stop = DateTime.Now.AddSeconds(10);
while (DateTime.Now < stop)
Thread.Sleep(100);
}, state);
if (callback != null)
result.ContinueWith(t => callback(t));
return result;
}
public string EndOperation(IAsyncResult ar)
{
ar.AsyncWaitHandle.WaitOne();
return "Hello!!";
}
}
}
这是客户端(命令行):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestClient
{
class Program
{
static void Main(string[] args)
{
var client = new ServiceReference1.AsyncTestClient();
var result = client.Operation();
Console.WriteLine(result);
Console.ReadLine();
}
}
}
如果你在服务上放置跟踪点,你可以看到WCF真正为你调用EndOperation.
异步客户端示例
首先,您需要生成异步代理.您可以通过右键单击"服务引用"(在项目的"引用"文件夹中),然后选择"配置服务引用"来完成此操作.选中"生成异步操作"复选框.
现在,您的客户端代理将拥有一些以前不存在的新成员.以下是如何使用它们:
// this is in the command-line test client
// no changes to your service required.
static void AsyncTest()
{
var client = new ServiceReference1.AsyncTestClient();
client.OperationCompleted += new EventHandler(client_OperationCompleted);
client.OperationAsync();
Console.WriteLine("Operation Running");
}
static void client_OperationCompleted(object sender, ServiceReference1.OperationCompletedEventArgs e)
{
if (e.Error == null)
Console.WriteLine("Operation Complete. Result: " + e.Result);
else
Console.WriteLine(e.Error.ToString());
}
| 归档时间: |
|
| 查看次数: |
6311 次 |
| 最近记录: |