Fetstil Fetstil Kursiv Understrykning linje färgläggning tabellverk Punktlista Nummerlista Vänster Centrerat högerställt Utfyllt Länk Bild htmlmode
  • Forum & Blog
    • Forum - översikt
      • .Net
        • asp.net generellt
        • c#
        • vb.net
        • f#
        • silverlight
        • microsoft surface
        • visual studio .net
      • databaser
        • sql-server
        • databaser
        • access
        • mysql
      • mjukvara klient
        • datorer och komponenter
        • nätverk, lan/wan
        • operativsystem
        • programvaror
        • säkerhet, inställningar
        • windows server
        • allmänt
        • crystal reports
        • exchange/outlook
        • microsoft office
      • mjukvara server
        • active directory
        • biztalk
        • exchange
        • linux
        • sharepoint
        • webbservers
        • sql server
      • appar (win/mobil)
      • programspråk
        • c++
        • delphi
        • java
        • quick basic
        • visual basic
      • scripting
        • asp 3.0
        • flash actionscript
        • html css
        • javascript
        • php
        • regular expresssion
        • xml
      • spel och grafik
        • DirectX
        • Spel och grafik
      • ledning
        • Arkitektur
        • Systemutveckling
        • krav och test
        • projektledning
        • ledningsfrågor
      • vb-sektioner
        • activeX
        • windows api
        • elektronik
        • internet
        • komponenter
        • nätverk
        • operativsystem
      • övriga forum
        • arbete karriär
        • erbjuda uppdrag och tjänster
        • juridiska frågor
        • köp och sälj
        • matematik och fysik
        • intern information
        • skrivklåda
        • webb-operatörer
    • Posta inlägg i forumet
    • Chatta med andra
  • Konto
    • Medlemssida
    • Byta lösenord
    • Bli bonsumedlem
    • iMail
  • Material
    • Tips & tricks
    • Artiklar
    • Programarkiv
  • JOBB
  • Student
    • Studentlicenser
  • KONTAKT
    • Om pellesoft
    • Grundare
    • Kontakta oss
    • Annonsering
    • Partners
    • Felanmälan
  • Logga in

Hem / Forum översikt / inlägg

Posta nytt inlägg


Asynkrona rop till MySql

Postades av 2009-06-24 10:09:59 - Alexander Westrup, i forum c# (c-sharp), Tråden har 12 Kommentarer och lästs av 1178 personer

Hejsan!

Jag har ett problem.
Min tanke är att när användaren för muspekaren över en div i en listview så skickas ett anrop till databasen som hämtar specifik data och visar den på sidan.

Allt detta fungerar MEN om man drar över många divar snabbt så ser man tydligt att anropen köas upp och visnings-diven visar olika värden under flera sekunder efteråt. Det jag vill är att om ett nytt anrop kommer så ska de andra tidigare avslutas. Lite som UDP kontra TCP :).

För att göra detta använder jag en listview med divar i som jag lagt till mouseover-event på. Javascript kallar på en metod i en webservice som sedan gör MySql-anropet. Anropet är till en stored procedure i MySql.

Jag vet inte om problemet är i ASP.NET-koden eller i MySql, men jag chansar på här :).


Svara

Sv: Asynkrona rop till MySql

Postades av 2009-06-24 10:15:11 - Niklas Jansson

Problemet är snarare i JS-koden. Webservicen får ett anrop och kommer svara - att bygga runt det är ju ett jävla jobb. JS-koden kan ju däremot säga att "mitt tidigare anrop var bara bullshit, det är det senaste jag vill ha". Har du skrivit JS själv, eller är det genererat?


Svara

Sv:Asynkrona rop till MySql

Postades av 2009-06-24 10:28:21 - Alexander Westrup

Jag har skrivit den själv, den är på 9 rader :).

Koden ser ut som följer:

function updateSummary(subCat) {

var lw = $get('itemPlaceHolderDiv');
var list = lw.getElementsByTagName("input");
var array = new Array();
for (var i = 0; i < list.length; i++) {
if (list[i].type == 'checkbox' && list[i].checked == true) {
array.push(list[i].value);
}
}
SummaryService.getSummary(subCat,array.toString(),onComplete,onFailed);
}

Har du något förslag på hur man skulle kunna skriva?


Svara

Sv: Asynkrona rop till MySql

Postades av 2009-06-24 10:33:36 - Niklas Jansson

Jag antar att du gör sjävla uppdateringen i onComplete?
Då borde du kunna utöka den med
onComplete(WhenWasThisSent)

och skicka med det a'la delegat. Kan inte exakta syntaxen, men något i stil med:

latestupdate = now()
SummaryService.getSummary(subCat,array.toString(),new function(){ return onComplete(latestupdate )}, onFailed);

Och sen utöka gamla oncomplete till:

function onComplete(WhenWasThisSent){
if(WhenWasThisSent < latestupdate)
return;
gammal kod
}

Är du med på principen?


Svara

Sv:Asynkrona rop till MySql

Postades av 2009-06-24 10:34:59 - Alexander Westrup

Jag är med på principen och återkommer med resultat eller fler tankar... :)


Svara

Sv: Asynkrona rop till MySql

Postades av 2009-06-24 12:24:49 - Oskar Johansson

En helt annan tanke: Har en "global" variabel i js som du använder ungefär såhär:

var updateTimeoutReference = false; //global variabel

onclick="updateFromServer(this);"

function updateFromServer(obj)
{
if(updateTimeoutReference)
  clearTimeout(updateTimeoutReference);
updateTimeoutReference = setTimeout(function()
 {
   updateTimeReference = false;
   
   alert(obj.id); //här ska du ha ditt riktiga anrop istället
   
 }, 100);
}


Vad du gör är att du sätter en timer på ett lågt värde (t.ex. 100 ms), och först efter 100 ms så kontaktar du servern. Dessutom så avbryter du en gammal timeout om en sådan finns. Vad som kommer hända är att om man hinner gå över till en annan inom 100 ms så kommer servern aldrig att kontaktas. Det sparar ganska mycket både för servern och klienten


Svara

Sv:Asynkrona rop till MySql

Postades av 2009-06-24 12:52:18 - Niklas Jansson

Det förbättrar ju lite, men (om jag inte missförstått - lunchkoma):
1. Dels får man ju en liten nersegning. 100 ms måste ju anpassas efter hur man drar musen och hur långsam uppkoppling det är, och blir det 500 ms istället så kommer det ju ge en impact.
2. Dels löser man ju inte problemet i de fallen då uppkopplingen är för långsam, då kommer fortfarande grejerna efter varandra. Och i teorin kan du ju få två "consecutive events" som ligger i fel ordning?

Det jag antar då är att det blir något i stil med:

Click--|---- 100 ms ----|- Anrop -------------------------|- Visa resultat -|
....................................Click -- |---- 100 ms ----|- Anrop -- ...


Om detta går att förstå =)

Däremot borde man kunna göra en combo. Eller är det kanske möjligt att avbryta själva anropet?


Svara

Sv:Asynkrona rop till MySql

Postades av 2009-06-24 14:50:30 - Alexander Westrup

Efter lite mer funderande så har jag fått mer förståelse för problemet i sig och problem med lösningarna här :) (döda mig nu inte om jag missförstått ;)). Saken är att med Niklas lösning så hämtar man fortfarande en massa från servern men väljer bara att visa lite av det, vilket inte är optimalt för användaren får vänta. Problemet med Oskars är väl ungefär samma, användaren får vänta onödigt länge.

Det jag vill göra är att kunna kapa i kön så att allt inte körs. Jag har hittat en blogg-post med tillhörande artiklar, men eftersom jag inte är så high på javascript så går det lite segt :/.
http://siderite.blogspot.com/2008_02_01_archive.html

Det ska tydligen finnas en array "window._webRequests" som innehåller köade webförfrågningar. Och ideen är att man loopar igenom den och försöker döda dem om det går. Mitt problem tror jag är att i bloggens exempel så dödas en startad, men jag vill döda en startad och göra att de andra som inte är startade än inte kommer att startas heller, detta för att sedan lägga till den senaste i kön (som förhoppningsvis körs direkt då).

Min modifierade kod är nu

function updateSummary(subCat) {
...
if (!window._webRequests) {
window._webRequests = Array();
}

KillRequests();
_webRequests[_webRequests.length] = SummaryService._staticInstance.getSummary(subCat, array.toString(), onComplete, onFailed);
}

function KillRequests() {
if (!window._webRequests) {
return;
}
for (var c = 0; c < window._webRequests.length; c++) {
if (window._webRequests[c]) {
var executor = window._webRequests[c].get_executor();
if (executor.get_started()) {
executor.abort();
}
}
}
}

function onComplete(args) {
$get(tbSummary).value = args;
}

function onFailed(args) {
$get(tbSummary).value = args._message;
}


Svara

Sv: Asynkrona rop till MySql

Postades av 2009-06-24 16:44:13 - Oskar Johansson

100 ms är nog i sammanhanget, men vid en snabb dragning med musen så kommer det spara väldigt mycket. Det jag tänker är att man kombinerar med Niklas variant.


Svara

Sv: Asynkrona rop till MySql

Postades av 2009-06-24 16:49:54 - Niklas Jansson

<b>>Problemet med Oskars är väl ungefär samma, användaren får vänta onödigt länge.</b>
Nja. Oskars lösning ser till att det inte blir nya anrop förrän det verkar som att användaren har bestämt sig. Det blir samma problem som originalet om användaren är "halvlångsam" (dvs. fortare än js-timeouten men snabbare än själva webbanropet).

Med lite tweaking på 100ms så tror jag nog att Oskars fungerar bättre än min, men det är nog svårt att få något som alltid funkar bra med den,.


Vad gäller din lösning: Yes, det är "rätt" lösning, förutsatt att den fungerar - avbryta utestående anrop. Det kombinerar du med fördel med Oskars metod.


Svara

Sv:Asynkrona rop till MySql

Postades av 2009-06-24 17:03:55 - Oskar Johansson

Man kan även tänka sig en lösning där timeouten börjar på 100 ms, men om det kommer flera väldigt nära inpå varandra så kan man börja dra upp timeouten uppemot kanske 800-1000 ms?


Svara

Sv: Asynkrona rop till MySql

Postades av 2009-06-25 00:05:35 - Niklas Jansson

Jo, precis - det ligger ju nära tillhands med en adaptiv lösning.

Spontan tanke är att hela tiden försöka hålla koll på hur lång tid ett anrop tar, och sen köra exponential decay eller va fan det kallas, typ:

init(){
Estimate = 100;
lambda = 0.7
}

onComplete(){
RealTime = GetThisCallTime();
Estimate = lambda * Estimate + (1-lambda)*RealTime
}


Estimate innehåller då hela tiden "typ" så lång tid som ett anrop tar. En enkel lösning då är att alltid ha en timeout på säg en tiondel av det, om man bara tänker på klienten och struntar i hur servern mår.

Och man kan ju även göra mer avancerade varianter där man kombinerar detta med information om hur användaren verkar bete sig, som du föreslår. Men då får man nog ha en situation typ google fast på en enda server för att det ska löna sig... =)


Svara

Sv:Asynkrona rop till MySql

Postades av 2009-06-25 13:06:07 - Alexander Westrup

Nu funkar det!

Det blev en tvådelad lösning.
Det första problemet var att det kom många anrop (som jag skulle döda), detta berodde på att jag använde mouseover som triggas hur många gånger som helst. Så den första delen av lösningen var att skapa ett mouseEnter-event som bara finns i IE...

Den andra delen av problemet var att om användaren drar snabbt så skickas många requests, detta löste jag med Oskars förslag med en fast tid på 150ms.

Jag kanske ger mig på att få väntetiden adaptiv, men det är inte säkert :).

Tack för alla svar

Här är koden för andra som vill se:

var currentElement;
var latestUpdate;
var updateTimeoutReference = false;

//Create mouseEnterEvent

function addEvent(_elem, _evtName, _fn, _useCapture) {
currentDiv = _elem;
if (typeof _elem.addEventListener != 'undefined') {
if (_evtName === 'mouseenter') {
_elem.addEventListener('mouseover', mouseEnter(_fn, _elem), _useCapture);
}
else if (_evtName === 'mouseleave') {
_elem.addEventListener('mouseout', mouseEnter(_fn), _useCapture);
}
else{
_elem.addEventListener(_evtName, _fn, _useCapture);
}
}
else if (typeof _elem.attachEvent != 'undefined') {
_elem.attachEvent('on' + _evtName, _fn);
}
else {
_elem['on' + _evtName] = _fn;
}
}

function mouseEnter(_fn, _elem) {
return function(_evt) {
var relTarget = _evt.relatedTarget;
if (this === relTarget || isAChildOf(this, relTarget)){ return; }
_fn.call(this, _evt, _elem);
}
};

function isAChildOf(_parent, _child) {
if (_parent === _child) {
return false;
}
while (_child && _child !== _parent) {
_child = _child.parentNode;
}
return _child === _parent;
}

//Summary functions

function updateFromServer(e, elem){
if (updateTimeoutReference) {
clearTimeout(updateTimeoutReference);
}
updateTimeoutReference = setTimeout(function() {
updateTimeReference = false;
updateSummary(elem);
}, 150);
}

function updateSummary(elem) {
var subCat = elem.attributes.getNamedItem("name").value;
var lw = $get('itemPlaceHolderDiv');
var list = lw.getElementsByTagName("input");
var array = new Array();
for (var i = 0; i < list.length; i++) {
if (list[i].type == 'checkbox' && list[i].checked == true) {
array.push(list[i].value);
}
}
SummaryService.getSummary(subCat, array.toString(), onComplete, onFailed);
}

function onComplete(args) {
$get(tbSummary).value = args;
}

function onFailed(args) {
$get(tbSummary).value = args._message;
}


Svara

Nyligen

  • 18:42 Hvor finder man håndlavede lamper
  • 18:41 Hvor finder man håndlavede lamper
  • 16:36 Allt du behöver veta om keramiskt
  • 16:14 Vem anlitar man egentligen när tak
  • 16:14 Vem anlitar man egentligen när tak
  • 16:13 Vem anlitar man egentligen när tak
  • 11:52 Noen erfaring med uttak hos Mostbe
  • 11:51 Noen erfaring med uttak hos Mostbe

Sidor

  • Hem
  • Bli bonusmedlem
  • Läs artiklar
  • Chatta med andra
  • Sök och erbjud jobb
  • Kontakta oss
  • Studentlicenser
  • Skriv en artikel

Statistik

Antal besökare:
Antal medlemmar:
Antal inlägg:
Online:
På chatten:
4 570 634
27 958
271 741
458
0

Kontakta oss

Frågor runt konsultation, rådgivning, uppdrag, rekrytering, annonsering och övriga ärenden. Ring: 0730-88 22 24 | pelle@pellesoft.se

© 1986-2013 PelleSoft AB. Last Build 4.1.7169.18070 (2019-08-18 10:02:21) 4.0.30319.42000
  • Om
  • Kontakta
  • Regler
  • Cookies