Sorry I cannot post the code but here is what is happening in detail.
User opens a form
it adds an event listener like:
GP.GlobalInfo.CommWCF.serviceClient.GetFilteredMessageCompleted += new EventHandler<GetFilteredMessageCompletedEventArgs>(serviceClient_GetFilteredMessageCompleted);
and then sends a asynchronous message to the server to get required data from database.
at the same time, the form adds another event listener and then sends another message:
GP.GlobalInfo.CommWCF.serviceClient.GetFilteredMessageCompleted += new EventHandler<GetFilteredMessageCompletedEventArgs>(serviceClient_GetFilteredMessageCompletedAnother);
so the client (form) is waiting for two messages to be returned.
as soon as messages are returned the form will display the data in a grid.
It seems not working as I expect. somehow messages get stuck somewhere.
so, I would like to know if my approach is wrong.
Another case is, there are five objects on the screen that I can click.
These five objects will use the same Class to create.
clicking an object brings a form with corresponding data.
if I click the first object, the form will add an event listener and sends a message to the server.
while the form is waiting for the data, I close the form, and then open another form by clicking another object.
The new form will add an event listener and sends a new message to the server.
Meantime, the server has been working the first form message, and returns the result to the second form.. not the first one(this has been closed).
this is what I experience right now.
can anybody give me some solution ASAP for the better behavior and understanding of silverlight and WCF.
I think I should send a stop message to the server or something..
-------old question----------
Hi I seem to have some problem with communicating between client and server .
when a form is opened, there are three listeners are opened. Each listener gets the required data.
I think (not sure) silverlight gets stuck while it communicates using those three listeners at the same time.
So, should I use only one listener running at the same time always in silverlight?
so like,
client asking A data from server
client asking B data from server
client save C data to server
those stuffs cannot be done at the same time ?
Do I always make sure of single communication process between client and server?
Thanks
The problem is that the event handler just tells "when that kind of operation is completed, call me". The event handler is not related to the specific call, but to the kind of operation.
If you are calling the same operation twice you cannot attach two event handlers and expect that each call invokes the respective handler. What happens is that when an operation is completed every handler attached to that operation will be invoked.
You can solve your problem as follows:
attach a single event handler for each specific operation
when you call yourOperation_Async() you can pass an identifier as userState (the last parameter)
inside the event handler you act accordingly to the identifer (you can retrieve it from the yourOperationCompledEventArgs.UserState), for ex. updating the correct form.
dummy example:
...
serviceClient.YourOperationAsync(formName);
...
void serviceClient_YourOperationCompleted(object sender, YourOperationCompletedEventArgs e)
{
if (e.UserState != null && e.UserState is string)
{
string formToUpdate = (string)e.UserState;
...
... update formToUpdate ...
...
}
}
Related
I have a modified asynchronous socket listener running based on Microsoft's example:
https://learn.microsoft.com/en-us/dotnet/framework/network-programming/asynchronous-server-socket-example
So it's always running and listening for incoming data.
I'm running it from the winform like this:
Task.Run(() => { AsynchronousSocketListener asl = new AsynchronousSocketListener(); });
I have a label on my form called LastMessage, once some data has been received on the socket I want to:
1. Make it visible
2. Change the text of the label to a value I extracted from incoming data from the socket listener.
I've searched around and tried to implement multiple solutions but couldn't get it working and I feel like I'm missing or misunderstanding something, what code needs to run on the form, what needs to run in the task, and most importantly, the server always has to stay up to listen for more incoming data, since all the solutions I saw are waiting for the task to end or return some value.
Thanks in advance.
I'm creating an OPC client, that reads data from the server. I need to show status of connection with server in real time on my form. Can this be done?
For example:
private void checkStatus()
{
testValue.Text = cl.GetConnectionState().ToString();
}
cl.GetConnectionState() - method that shows connection status.
Add a timer to call that function. Function itself is fine, and should update the status correctly.
Although, if you want to do it right, I will say put this code in StateChange event handler. That way, your code will not run this function forever, and instead wait for the state to change.
I'm writing writing a program to perform some basic tests and I'm trying to get it to automatically login. It seems that the documentComplete event would be overused if I had to use it for every possible scenario.
I saw a number of examples with Browser ReadyState but I'm unable to get them to work.
I have a simple method which finds the username element, enters the user name, invokes the click method, finds the password element, enters the password, and invokes the click method.
If I delay the process with a messagebox then it works because it gives the page time to load.
private void fillInLogin()
{
browser.Document.GetElementById("des_LoginName").InnerText = "myLogon";
browser.Document.GetElementById("btnLogOn").InvokeMember("click");
//*********WHAT CAN I PUT HERE TO CHECK TO SEE IF THOSE ELEMENTS EXIST***********
browser.Document.GetElementById("des_Password").InnerText = "myPassword";
browser.Document.GetElementById("btnSubmit").InvokeMember("click");
}
Have you looked into subscribing to the WebBrowser.DocumentCompleted event? It takes all of the guesswork out of waiting for a page to load, and is actually the proper way to do it. You can't really rely on a server response to be completed within a given wait period. Usually the only guarantee is the timeout period of your client code, but you don't want to force a wait to the timeout maximum. Using a threaded request and an event listening for the callback will allow you to make the request and continue to provide a responsive UI to the user.
I'm working on a really big project developed by two teams, one (mainly) for the database, and one (where I am) mainly for the GUI and helper classes as an interface between GUI and DB.
Obviously, there are errors in communication, and - of course - we can't assume 100Mbit bandwidth & super-fast server computer.
Language is C# .NET, target "framework" is WPF and Silverlight.
When a user clicks a button, the GUI asks the DB (through helper classes) for information. Let's say... pizza types. The server should answer "{Funghi,Frutti di mare,Prosciutto}". When DB sends his answer, we receive a "database.Ready" event and fill our datagrid.
BUT if the user clicks the button while we haven't received the answer yet, the GUI sends an another request to the database. And the whole system tries to serve the user.
But it can't, because when the second request is sent, the first is disposed when we want to read it. So NullReferenceExceptions occur.
I've solved this by implementing kind of a semaphore which closes when user input occurs and opens when the Ready event (the functions it calls) finishes working.
Problem:
If I don't receive the Ready event, no user input is allowed, but this is wrong.
Question:
Is there a common (or at least, working) solution to stop waiting for the Ready event and...
1) re-sending the request a few times, hoping we receive our pizza types?
AND/OR
2) Dropping the request, tell the user that database failed to send the answer, and re-open the semaphore?
I can't post code here as this code is the property of a corporation, I'd rather like to have theoretical solutions, which are okay for professionals too.
Sorry for the long post, and thank you for your answers!
I assume that you are already using a background thread to dispatch the query to the database and wait for it's response. You can use the Task API that was introduced in .NET 4.0 to cancel such a request. For that, you pass in a CancellationToken that signals the status to the executing task. You can obtain a CancellationToken via a CancellationTokenSource as shown in the following code:
public partial class MainWindow : Window
{
private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
public MainWindow()
{
InitializeComponent();
}
private void Button_CallDatabase(object sender, RoutedEventArgs e)
{
Task.Factory.StartNew(CallDatabase, _cancellationTokenSource.Token);
}
private void Button_OnNavigate(object sender, RoutedEventArgs e)
{
// If you navigate, you can cancel the background task and thus
// it will not execute any further
_cancellationTokenSource.Cancel();
}
private void CallDatabase()
{
// This simulates a DB call
for (var i = 0; i < 50; i++)
{
Thread.Sleep(100);
}
// Check if cancellation was requested
if (_cancellationTokenSource.Token.IsCancellationRequested)
{
Debug.WriteLine("Request cancelled");
return;
}
Debug.WriteLine("Update Controls with DB infos.");
}
}
Note that this example is simplified, you can and should use this in another component (e.g. view model).
If you still want to use the Ready event, you could also just unregister from it when you navigate away, so that no further actions will be performed when it is raised.
I have a silverlight 4 web app that needs to communicate with a server by accessing the ASMX web service on the server.
I have a list(yes, the array), of objects that I need to send(one by one) as a parameter to the service. However looping through the list and running the method(objecttosend); will not work because I need to send then one after another and Silverlight seems to only support Async(presumably to not lockup interface - makes sense).
So I tried this:
public void SendNextPart()
{
if (partsToSend.Count > 0)
{
Part thisPart = partsToSend.Dequeue();
fuWS.createPartCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(fuWS_createPartCompleted);
fuWS.createPartAsync(thisPart);
}
}
Queue<Part> partsToSend = new Queue<Part>();
void fuWS_createPartCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
SendNextPart();
}
Which, as far as I can understand it, will check to see if the List has parts to send, then run the webservice(called fuWS) method and delete that part from the partsToSend List. Once it gets the completed event it should then run the SendNextPart method again and send the next part.
However what is happening(picked this up by watching HTTPwatch) is that it sends the first part, then after that is sends 2 parts at once and then after that more and more, all at once. Almost as if it is receiving the completed event before it has actually sent to the server and run the method successfully.
Please help, this is bugging the hell out of me, and it completely breaks what I need to do :'(
I don't see the SendNextBuffer method that you're calling in the web service callback event handler. But in any case, at best your code has a race condition. If the web service completes and returns before the partsToSend.RemoveAt line is executed (theoretically possible) then you could be making the next request before you've removed the one you just sent.
So first, you should check to make sure you've included all the code in your example unless you meant for SendNextBuffer to say SendNextPart.
Secondly, you should move the partsToSend.RemoveAt line before the web service call.
Finally, you should probably change the partsToSend list into a Queue<Part> (first in, first out) or Stack<Part> (last in, first out) instead since that is what you're using it as.
Ok, so after using Debug.WriteLine, I realized that I was being an idiot.
Check out this line:
fuWS.createPartCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(fuWS_createPartCompleted);
What this was doing was adding a new event handler every time it had to send a new part. So the second part sending now had two callback then the third would have more and so on increasing exponentially.