I try to generate a lot of User in my DB using a WCF service using a loop.
The script and the web service are running locally (Cassini).
FormWCFClient formClient = new srForm.FormWCFClient();
User user;
int nbUser = 20000;
for (int i = 0; i < nbUser; ++i)
{
user = new User();
user.Email = String.Format("{0}#example.com", i.ToString());
formClient.AddUser(user); // Add the user in DB
}
formClient.Close();
The problem is that around 3300 calls an EndpointNotFoundException is launched with the following innerException : "Unable to connect to the remote server".
I need to wait around 20 seconds in order to be able to continue the process without error (until the next range of 3300 calls).
Is it a code problem or a server limitation ?
You could create a new operation in your service that takes a list of users as a parameter. Then you would call it once with the list instead of calling the existing operation 20000 times with one user. It would reduce the load on the network and ease the use of transactions.
If not possible, then activate WCF tracing and check what happens when the call fails.
Related
I am developing a game using TCP. The clients send and listen the server using TCP. When the server receives a request, then it consults the database (SQL Server Express / Entity Framework) and sends a response back to client.
I'm trying to make a MMORPG, so I need to know all the players locations frequently, so I used a System.Timer to ask the server the location of the players around me.
The problem:
If I configure the timer to trigger for every 500ms a method that asks the server the currently players location, then I can open 2 instances of the client app, but it's laggy. If I configure to trigger for every 50ms, then when I open the second instance, the SQL Server throws this exception often:
"The connection was not closed. The connection's current state is open."
I mean, what the hell? I know I am requesting A LOT of things to the database in a short period, but how do real games deals with this?
Here is one code that throws the error when SQL Server seems to be overloaded (second line of the method):
private List<CharacterDTO> ListAround()
{
List<Character> characters = new List<Character>();
characters = ObjectSet.Character.AsNoTracking().Where(x => x.IsOnline).ToList();
return GetDto(characters);
}
Your real problem is ObjectSet is not Thread Safe. You should be creating a new database context inside ListAround and disposing it when you are done with it, not re-using the same context over and over again.
private List<CharacterDTO> ListAround()
{
List<Character> characters = new List<Character>();
using(var ObjectSet = new TheNameOfYourDataContextType())
{
characters = ObjectSet.Character.AsNoTracking().Where(x => x.IsOnline).ToList();
return GetDto(characters);
}
}
I resolved the problem changing the strategy. Now I don't update the players positions in real time to the database. Instead, I created a list (RAM memory) in the server, so I manage only this list. Eventually I will update the information to the database.
We are developing using VS2010 and MVC4, deploying our web app on an IIS 7.5 on Windows7.
Our project has a long running process for which we want to display status and progress.
In order to accomplish this we have a small serializable class with properties that describe the current status. The long operation pseudo code goes like this:
int curentPercentComplete = 0;
EngineStatus status = new EngineStatus();
while (!done) {
status.PercentComplete = curentPercentComplete;
Session['status'] = status;
// do lengthy operation
curentPercentComplete = compute();
done = isJobFinished();
}
We also have an other controller action that tries to retrieve the current status from the session
which then encodes to json and returns it to the browser via an Ajax request.
Our problem is that we always seem to get the last saved data from the previous request, in other words the session object does not seem to update the Session['status'] field during the execution of the while block.
We have tried the session state mode both InProc and StateServer with exactly the same behavior.
Thanks in advance.
It turns out that the MVC framework performs a single update of the session data at the end of the request which means that only the last value is saved.
Since the "lengthy" operation is performed in a single request-response cycle, the idea of storing intermediate status information in the session is plain wrong.
I'm developing a app where a list is automatically refreshed every 15 sec. To do so, I load the store every 15 sec from server (sending the params) via php page linked to a postgreSQL DB. So far, so good, and it works OK.
Buy I have noticed that every time the store is loaded, it sends two requests to the server (read + create). While the read request is necessary to load new elements to the store, the create is completely useless, because it sends the whole store as payload and receives nothing making use of the network for nothing.
How can I make the store to read, and only read, from the server when it loads?
Thanks
Some week sago I had some unexpected creates too. Googles learned me that there is an issue with Sencha with store.load(). It seems loaded records stay phantoms after loading. A store.sync() will create all records in a store that are phantoms (means they are not yet in back end).
I have next code in my on load callbacks:
callback: function(records, operation, success) {
var x = records.length;
for (i = 0; i < x; i++) {
records[i].phantom = false;
}
}
This solved my problem.
I started using Visual Studio load test a few days ago. I am calling a URL and get the average response time results. My problem is I want the test tool send 1 user 1 request. But the test tool sends 1 request every 5 secs. How can I limit the number of total request. I want to connect my code to an MDB file which has 2000 records. And I want 1 user to send these 2000 records one by one.
My current code is as below. Please help.
Best regards
public override IEnumerator<WebTestRequest> GetRequestEnumerator()
{
WebTestRequest request;
if (true)
{
request = new WebTestRequest("http://192.168.1.36:8888/webgis_net/wms.ashx?NCWS=OGM&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&BBOX=30.4181109599491,40.4702930755111,30.4195710292824,40.4717531448444&SRS=EPSG:4326&WIDTH=256&HEIGHT=256&LAYERS=Uydu,ILCELER,ILLER,MAHALLE_HAT,CASN,ORMAN,ORMAN_HAT,B2,B2_HAT,ZIRAAT,ZIRAAT_HAT,SU,SU_HAT,NOKTA,OSN&FORMAT=image/png");
request.Method = "GET";
request.Timeout = 180;
yield return request;
}
}
When you create your new Load Test do the following in the New Load Test Wizard:
In the Load Pattern tab check the Constant Load option and set the User Count = 1
In the Test Mix Model tab check the Bases on the number of tests option
In the Test Mix tab add only the Web Test you want
In the Run Settings tab check the Test Iterations option and set the Test Iterations = 2000
With this way, only one virtual user will be created and the Tests (2000) will be one after the other but not concurrently
I am using the following code to investigate what happens when you fail to close the proxy:
class Program
{
static void Main()
{
for (int i = 1; i < 500; i++)
{
MakeTheCall(i);
}
Console.WriteLine("DONE");
Console.ReadKey();
}
private static void MakeTheCall(int i)
{
Console.Write("Call {0} - ", i);
var proxy = new ServiceReference1.TestServiceClient();
var result = proxy.LookUpCustomer("123456", new DateTime(1986, 1, 1));
Console.WriteLine(result.Email);
//proxy.Close();
}
}
The service is using net.Tcp binding, WAS hosted, all default values.
Running it, I get a timeout when i > 400. Why 400 - is this a setting somwhere? I expected it to be much less - equal to maxConnections.
By not closing the proxy, you are maintaining a session on the service. The maxConcurrentSessions throttling attribute controls how many sessions the service can accommodate. The default (in .NET 4.0) is 100 * Processor Count, so I am guessing that you have 4 processors (or cores) = 400 concurrent sessions?
The reason your test code is timing out is probably due to the default WCF service throttling and doesn't have anything to do with not disposing of the proxy object. To conserve client-side resource, you should always properly dispose the proxy instance.
I believe that a service host will only create up to 16 instances of a service by default which may be even less if the binding is set to use session of some sort. You're flooding it with around 400 requests within a few seconds. There are a set of WCF performance counters you can fire up and view the instancing of a WCF service. I knew all that prep for the WCF certification exam would come in really useful sometime :)