Currently, my WCF service has an operation contract that appears like the following:
[OperationContract]
int DoSomething1(int param1, int param2);
The publishing references for asynchronous calls to this service operation contract are the following
void DoSomething1Async(int param1, int param2)
And then a completed event:
EventHandler<DoSomething1EventArgs> DoSomething1Completed
Is there any way to force this behavior (from my reading, it appears as though this is the "Event-Based Asynchronous Pattern") to publish as the Asynchronous Programming Model (from my understanding, it would be deployed as IAsyncResult DoSomething1Begin() and the corresponding ...End() function)?
Or even possible to implement the more modern async approach with (from my reading/understanding) the Task-Based Asynchronous Pattern (async/await) where the async methods return Task<TResult>?
I'm having a hard time getting around the confines of event-based async.
Thank you in advance!
Related
How to get result from the Service, if task run asynchronously?
If a task is started synchronously in main thread, there is no problem:
Object result = serviceInstanceInActivity.callMethod();
But if the task runs in other thread, we have a problem:
void asyncMethodInService() {
new MyTask().execute();
}
class MyTask extends AsyncTask<Void, Void, Result> {
// implementation of the others methods
public void onPostExecute(Result result) {
// We need to send data to Activity here
}
}
Of Course, it's work via ServiceConnection. In usual class, I would use interfaces as callback, but if I do same here, the Activity instance will leaked in Service via callback.
So, what is recommended way to deliver data in this cases?
I would use LocalBroadcastManager to broadcast an Intent containing the result, so that any interested activities can register for and receive the broadcast when the service completes its task.
If the data is complex and is not practical to pack into an Intent, you need to get a bit creative. You should probably use a ContentProvider and put a content URI into the intent which the activities can then use to query for the result. Or you might be able to store the result on a static singleton (or on your application instance) and just have the activity retrieve the updated value when it receives the broadcast. It depends on your requirements.
Hope that helps!
I have created one WCF service which performs a lengthy operation asynchronously using Asynch pattern. I have referred to below link to implement BeginAddNumbers and EndAddNumbers methods in the ServiceContract.
http://aspalliance.com/1335_Asynchronous_Pattern_in_Windows_Communication_Foundation.5
Everything is working fine. But I dont understand why we require this approach?
Even though its asynchronous operation on server, client will still blocked and we
have to invoke this operation asynchornously on client as well.
So instead of implementing operation asynchronously on server it's always
better to invoke operation asynchronously on client side to have responsive UI.
Can anyone help me to understand concept of implementing asynchronous operation on server side? Any practical example where I need to play around AsyncPattern=true in conjunction with OperationContract ?
Adding client code. Client is implemented using WPF application
private void button1_Click(object sender, RoutedEventArgs e)
{
MathOperationClient c = new MathOperationClient();
Task t = new Task(new Action(() =>
{
///Even if AddNumbers is is implemented as asynchronous operation
///second call to AddNumbers get chance only after completing below
///call.
///Note: AddNumbers method takes 10 sec to execute
int nResult = c.AddNumbers(2, 3);
this.Dispatcher.BeginInvoke(new Action(()=>{
label1.Content = nResult.ToString();
})
, null);
}));
t.Start();
Task t1 = new Task(new Action(() =>
{
///Below method is invoked only after executing first call ( above call with parameters 2 and 3 )
///in other words below call is blocked for 10 seconds.
///So what is advantage of implementing asynchronous AddNumbers method on server side?
int result = c.AddNumbers(5,5);
this.Dispatcher.BeginInvoke(new Action(() =>
{
label2.Content = result.ToString();
})
, null);
}));
t1.Start();
}
Thanks, Hemant
this post has some information.
in general:
In case of WCF, the realproxy is of type System.ServiceModel.Channels.ServiceChannelProxy. This proxy implementation calls service method synchronously even if we call it using BeginInvoke.
WCF only issues asynchronous calls if the method that is called on a proxy begins with BeginXXX() and is decorated with [OperationContract(AsyncPattern=true)] attribute.
I like the idea to implement this server side; and clearly indicate this by naming the operation accordingly. After all, if a call is asynchronous in nature, why give the client the choice?
Another reason is scalability: doing it server-side decouples the request from the WCF dispatcher thread. This means that WCF threads will not be blocked.
See here for an example.
You could even decide to make it a one way call; and have the client poll at regular intervals; which is, in fact, my favorite approach.
I (new to WCF) am writing a WCF service that acquires and analyzes an X-ray spectrum - i.e. it is a long-running process, sometimes several minutes. Naturally, this begs for asynchronous calls so, using wsDualHttpBinding and defining the following in my ServiceContract
[ServiceContract(Namespace="--removed--",
SessionMode=SessionMode.Required, CallbackContract=typeof(IAnalysisSubscriber))]
public interface IAnalysisController
{
// Simplified - removed other declarations for clarity
[OperationContract]
Task<Measurement> StartMeasurement(MeasurementRequest request);
}
And the (simplified) implementation has
async public Task<Measurement> StartMeasurement(MeasurementRequest request)
{
m_meas = m_config.GetMeasurement(request);
Spectrum sp = await m_mca.Acquire(m_meas.AcquisitionTime, null);
UpdateSpectrum(m_meas, sp);
return m_meas;
}
private void McaProgress(Spectrum sp)
{
m_client.ReportProgress(sp);
}
Where m_client is the callback object obtained from m_client = OperationContext.Current.GetCallbackChannel(); in the "Connect" method - called when the WCF client first connects. This works as long as I don't use progress reporting, but as soon as I add progress reporting by changing the "null" in the m_mca.Acquire() method to "new Progress(McaProgress)", on the first progress report, the client generates an error "The server did not provide a meaningful reply; this might be caused by a contract mismatch..."
I understand the client is probably awaiting a particular reply of a Task rather than having a callback made into it, but how do I implement this type of progress reporting with WCF? I would like the client to be able to see the live spectrum as it is generated and get an estimate of the time remaining to complete the spectrum acquisition. Any help or pointers to where someone has implemented this type of progress reporting with WCF is much appreciated (I've been searching but find mostly references to EAP or APM and WCF and not much related to TAP).
Thanks, Dave
Progress<T> wasn't really meant for use in WCF. It was designed for UI apps, and may behave oddly depending on your host (e.g., ASP.NET vs self-hosted).
I would recommend writing a simple IProgress<T> implementation that just called IAnalysisSubscriber.ReportProgress directly. Also make sure that IAnalysisSubscriber.ReportProgress has OperationContract.IsOneWay set to true.
I am trying to create a WCF service that supports asynchronous calls. I followed all samples and tutorials I could find, and all of them have the customary pattern of one synchronous method, and the async Begin and End such as:
[OperationContract(AsyncPattern = false)]
string GetData(int value);
[OperationContract(AsyncPattern = true)]
IAsyncResult BeginGetData(int value, AsyncCallback callback, object asyncState);
string EndGetData(IAsyncResult result);
However, only the synchronous GetData gets called, no matter what I do on the client side. Fiddler tells me that the message is always the same:
<s:Envelope
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><GetData
xmlns="http://tempuri.org/"><value>0</value></GetData></s:Body></s:Envelope>
When I remove the synchronous GetData interface, the async method now is properly called.
Is this normal behavior? Is there anything else I should do to support sync and async versions of a method?
This is a common misconception. You assume that you need to make the server asynchronous in order for the client to be able to make async calls. This is not true. Server and client are 100% independent. They are separated by a binary wire protocol.
The message that you see in Fiddler is always the same because SOAP does not know anything about sync or async. At the SOAP level your decision does not manifest itself. For that reason the client cannot observe your server-side decision, either.
This means you can just make the server synchronous in still have a truely async client, or the other way around.
In any case, you should only implement one pattern on the server: Either sync or async. Never both. Get rid of one of your implementations. From a functional standpoint it doesn't matter which one stays.
I'm pulling up important information from the comments here:
It is hard to fit an explanation about when to use server-side async
into this comment box. In short, don't use it on the server by
default. Use it if special circumstances make it attractive or
necessary.
On a meta-level let me point out that async IO has become
a fad that should not be followed lightly. The community is in a very
unfortunate state of misinformation about this right now.
I am trying to use asyn CTP with WCF, but I have problems because Task is not serializable.
I have installed CTP v3.
Is it possible to use asyn CTP with WCF? is it need to configure something more than install only the CTP?
I am thinking that if is not possible to use async CTP jet, perhaps instead of using async CTP in the service side, I can implement async method with async CTP that call to the normal methods (not async methods) of the service. is this a good option? In this case the service does not implement async methods.
Other option is in the service side, implement the async methods with the begin/end methods, wrapping this two methods in a task using Task.Factory.FromAsync method. But this is more work.
So My question is, if I want that the client is not blocked while it waits for the service response, I can use two solutions. First use async CTP in the client that call normal methods of the service, or use async methods in the service using Task.Factory.FromAsync. Which is the best option? Why?
Thanks.
Daimroc.
I'm not sure about VS 2010 with Async CTP, but with VS 11 Beta (which you should probably use anyway), you can simply define an operation that returns a Task:
[OperationContract]
Task<string> GetData(int value);
And then implement it using async:
public async Task<string> GetData(int value)
{
return await …;
}
I would assume the same approach would work with Async CTP, but it's just an assumption.
The simplest way to achieve a non-blocking client call is on the client side, for two reasons:
Client side asynchronous methods can be generated by the existing VS tools
Passing Task over service boundary would require you write your own synchronization functionality.
To generate client-side Task<> based (and therefore async/await compatible) methods for a service:
In VS11, a new checkbox exists: "Generate Task-based methods" under "Allow generation of asynchronous operations" in the Configure Service Reference dialog. (I believe it is not yet documented)
For the CTP you can use the extension described here to generate Task based methods.