If there is more than one request occurring from different clients simultaneously then the value of Hub.Context.ConnectionId changes during the execution of the handler.
Say I've got 2 clients connected with client Ids A and B, and I've got a method on my Hub called foo(). I send a request from A to the Server invoking foo(), then whilst the request from A is being processed I send a request from B invoking foo(). At the start of the processing of A's request Hub.Context.ConnectionId == A but at the end of the method call Hub.Context.ConnectionId == B.
Should I be copying the Hub.Context? At what point should I do this?
It doesn't need to be thread safe since Hub instances aren't static so you don't need to copy anything.
They are created per call. So each call from the client will create a new Hub instance and HubContext.
This doesn't directly answer your question, but my usual workflow is to set a value on the caller when they first connect, which may accomplish what you need?
Caller.clientId = Guid.NewGuid();
Related
I have a web service that I want to call from one of my asp.net classes.
I can call my web service successfully.But now I need to call this service asynchronously. I need to call it and NOT wait for the service to complete execution. I don't need to process a response from the service and don't need to verify if the service executed successfully. All I want is to be able to call the service and be free to do other things.
You need to consume web service asynchronously.
Goto and check
AddServiceReference -> Advance -> generate asynchronous operations.
after this async callback events will be available to you for every method
Suppose you have ABC method in you service when you will consume it by as sync these methods will be available to you in your application
1>ABC (fire and wait for output)
2>ABCAsync(fire and forget)
3>ABC callback event(get fired <if ABCAsync is called> when data available in your application)
One way to implement a fire-and-forget approach is to use the IsOneWay property on the OperationContract attribute, like this:
[OperationContract(IsOneWay=true)]
public void SomeMethod(string someValue);
When set to true, the operation won't return a message. Note that methods marked as one-way cannot have return types or ref or out parameters (which makes sense). It also should not be confused with asynchronous calls, because it's not the same thing (in fact, a one-way call can block on the client if it takes a while to get a connection, for example).
See OperationContractAttribute.IsOneWay Property for more information.
Have you tried this:?
http://msdn.microsoft.com/en-us/library/bb885132(v=vs.110).aspx
this is another way to do it, check it out.
I'm writing a code that sends 2 codes to 2 different emails (to check that owner of both emails are the same person). And I got the error:
System.InvalidOperationException: An asynchronous call is already in progress. It must be completed or canceled before you can call this method. Well I can simply avoid this error sending the second email after the sending of the first one completes, but the question is that if so many users at the same time request email sending (forgotten password, email change, registration, ...) would it cause problem? or I will get this error only when they are executed repeatedly at the same page?
Thanks in advance,
Ashkan
The purpose of the SendAsync method is not to block the calling thread; however, you must wait for the SendAsync method to finish before you can send a new email on the same SmtpClient instance. In other words, create 2 instances, one for each email, and send them both asynchronously if you want.
From MSDN:
After calling SendAsync, you must wait for the e-mail transmission to
complete before attempting to send another e-mail message using Send
or SendAsync.
As Icarus pointed out, you have to wait for the SendAsync to finish before calling it on the same instance. In addition to that, it is possible to have ThreadPool starvation, but your mileage will vary based on your implementation. Internally, SendMailAsync uses a ThreadPool thread to perform the task. I wouldn't be concerned if it's just an email here and there though.
No Separate instances won't be a problem. if many users send requests at the same time they each will be different instances.
I would create a WCF service with some methods. One of these methods (that is, the Connect method) should be the first to be called in order to use the service: in other words, before you can use all other methods of service, must be called the Connect method. For this reason, I defined it with IsInitiating property set to true, and I have defined the other methods with this property set to false.
In addition, the node offering the service must be able to refuse the connection request from another node (for example, if other nodes are already using the service): is there a way to prevent the use of the service?
Thanks a lot!
Well, sure.
First understand that by default, WCF services are an "instance-per-request" construct; The HttpApplications that IIS maintains in the app pool will "new up" a copy of your service contract class, make the call pertaining to the request, then the object will go out of scope and be destroyed. You can override this by stating that your service should run in "instance-per-session" mode:
[ServiceContract(SessionMode = SessionMode.Required)]
public interface IMyServiceContract
{
...
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class MyServiceImplementation: IMyServiceContract
{
...
}
Now, when your service is called, a "session" is established between client and server, and a single copy of your class will be created and remain in memory for the life of that session (unless the app pool is refreshed, which can happen automatically or by a manual action within IIS). This is the first step.
Now, you can do one of two things:
Simply check in any method besides Connect() whether Connect() has been called on this instance since its creation. If not, throw out.
Have the Connect() method return some instance-scoped token or GUID that the client must then pass to all other method calls. If the GUID the caller provides doesn't match the one kept in instance memory, then throw out of the method.
Understand that sessions can time out between requests. If this happens, your current instance will leave scope and be destroyed, and a new instance will be created to handle subsequent requests. I would thus opt for the second option even though the system can identify instances based on their session; the GUID ensures that both the client AND service instance have not changed since the last call.
I need to be able to cancel async calls made to my webservice. One solution I have is to use manage my own threads, and use synchronous methods from the SOAP client. This works fine and it needs some more fine grained thread management.
If I used any of these two patterns provided from adding a web service reference, say:
var Client = new ASL_WS.SvcSoapClient()
IAsyncResult result = Client.BeginAuthenticateUser(Email, Password, new AsyncCallback(AuthCompleted));
or
var Client = new ASL_WS.SvcSoapClient()
Client.AuthenticateUserCompleted += AuthCompleted;
Client.AuthenticateUserAsync(Email, Passsword);
do any of these two patterns give me a way of cancelling the request? One use case could be: a user logs in, but wants to cancel before the authenticate call completes.
Of course, I could implement this differently by modifying the asyncState passed to these calls, and setting it to disable UI update, but it's not what I'm looking for.
Could I just just cancel all outstanding operations. Does Client.Abort() cancel such operations. What if there are many async requests, are all cancelled? Are there any other API methods that can do this?
Yes, you can use Abort method but keep below notes in mind. You can also use CancelAsync.
Abort notes: http://msdn.microsoft.com/en-us/library/aa480512.aspx
When you call the Abort method, any outstanding requests will still complete, but they will complete with a fault. This means that if you are using callbacks, your callback function will still be called for each outstanding request . When the EndInvoke method is called, or in our case, the wrapper function EndDelayedResponse, then a fault will be generated indicating that the underlying connection has been closed.
CancelAsync example: http://www.codeproject.com/KB/cpp/wsasync.aspx
Is it possible to wait on a callback in WCF? Given this article, I will raise a callback in my WCF service, but I want the client (a seperate application) to only proceed (ie go to the next line of code, e.g. close a form etc, after the callback is raised. So I need to block until the callback is raised.
How could I do this?
Instead of using callbacks, you could call the service synchronously from the client.
If the client does not require any data to be returned, you could return a void, and the client will still wait for the call to complete.