Hej!! Om jag har fattat det hela rätt så är det komponenten MYComp.MinClass som du kör i MTS? Om så är fallet så är det i den komponenten som du skapa ditt object context och inte i själva klienten. Tack Niklas! Ett ytterligare påpekande, använd _inte_ New när du skapar ditt objekt. Använd istället CreateObject. Så här alltså: hmm håller inte rikigt med.. lite riskabelt att använda new i mts komponenter? hmm, skulle inte new vara snabbar än createobject ??? Vet du skillanden mellan de två sätten att instansiera objekt ?? Vad menar du (Christoffer) med att new inte är com? Jodå, jag vet hur instansieringen av ett objekt fungerar (i bägge fallen). Jag kan hålla med om att man i en klient som kör utanför MTS/COM+ kan använda new för att skapa en instansiera ett objekt, men jag ser ingen jätteanledning att göra så. Prestandaskillnaden är antagligen inte särskilt märkbar, om man inte ska instansiera objektet flera gånger eller något. Jag tycker att du har en poäng med flexibiliteten med att använda createobject, men däremot håller jag inte med om att det skulle vara något problem om klienten använder new för instansiera MTS komponenten. Däremot så är det precis som du visar med ditt exempel ett stort problem om en MTS komponent skapar en annan MTS komponent med hjälp av new. precis, det var så jag försökte säga också. Jag hade tidigare inte noterat att vi diskuterade klienten (eftersom exemplet diskussionen startade med utnyttjade MTS, dock felaktigt som du beskrev för Kristoffer (OBS, inte jag alltså...)), men ja, jag håller med om att det går bra att använda new i klienten, men jag anser inte det vara motiverat. Men i det läget är det som sagt mer en smaksak, om man vill ha flexibilitet eller viss prestandaförbättring.GetObjectContext(Transaction Server)
Sitter och leker lite med Transaction Server. Så här der det ut:
<b>
Dim obj_Context as ObjectContext
Set obj_Context=GetObjectContext()
Dim str as String
Dim min_komp as MYComp.MinClass
Set min_komp as new MYComp.MinClass
str = min_komp.GetMessage
obj_Context.SetComplete
</b>
Följande problem uppstår:
Efter att GetObjectContext anropats är obj_Context fortfarande Nothing, vilket gör att obj_Context.SetComplete misslyckas.
När jag gör <b>Set min_komp as new MYComp.MinClass</b> så börjar komponenten snurra i Transaction Server.
Någon som vet varför detta inte funkar??
Tack för hjälpen!!
//KristofferSv: GetObjectContext(Transaction Server)
Glöm inte bort att sätta en referens till Microsoft Transaction Server Type Library.
//NiklasSv: GetObjectContext(Transaction Server)
Tror det var det svaret jag ville ha.
//KristofferSv: GetObjectContext(Transaction Server)
''' Inte så här
''' Set minkomp As New mycomp.myclass
''' Detta är korrekt
Set minkomp = CreateObject("mycomp.myclass")
Varför ska man göra så då? Jo, därför att New är inte COM. New är ett VB-påhitt.Sv: GetObjectContext(Transaction Server)
du kan mycket väl använda new i klienten utan några problem .. New kommer dessutom i 90% av fallen att vara snabbare, men i en komponent är det i MTS lite riskabelt att använda NEW för att skapa andra com komponenter i MTS.
Dock kan du med fördel skapa dina connections och recordsets med new i en komponent och borde så gör aför bäst prestanda...
En annan liten 'note'.. OM du skall använda new, gör det inte i variabel deklarationen:
dim oMyObject as New MyComp
----
utan använd
Dim oMyObject as MyComp
set oMyObject = New MyComp
Det första sättet kommer ge dig ngn prestanda skillnad från createobject. Anledningen till det är att om vi deklarerar objekts variabeln med new, kommer vb att vid varje anrop göra en koll mot objektet för att se om det är instansierat. Använder vi set skippas den kollen och voila det går snabbare.
Det finns en massa mer för och nackdelar med det hela, men detta är den som för mig varit mest avgörande.Sv: GetObjectContext(Transaction Server)
Jag skulle vilja säga att det är helt felaktigt att använda new när man ska instansiera en komponent som kör i mts. Som sagt så är new inte com, utan bara ett vb-påhitt. MTS däremot är 100% COM, alltså kan man inte få ett objekt att köra i mts om det inte skapas genom COM. ADO connections etc kan man visserligen skapa med new, eftersom dessa inte kör i mts, men jag ser ingen anledning, mer än möjligen en _viss_ prestandaskillnad.
Dock har jag aldrig hört någon 'säker källa' säga att new alltid är snabbare än createobject, utan jag har hört lite av bägge. Alltså är det inte garanterat en prestandaförbättring att använda new istället för creatobject.
I VB.NET är det däremot helt OK att använda new, i alla lägen. Det fungerar även i C#.Sv: GetObjectContext(Transaction Server)
New hoppar över ett par steg i uppletandet av clsid och dylikt, vilket inte kan bli annat än snabbare. Det är också anledningen till att det bara är riskabelt och inte direkt fel att skapa object med new i mts.
För att köra ngt i mts ändras en nyckel i registret för kompnenten, den ändrar sökvägen till kompnenten från den aktuella dll till mts miljön iställer .. Detta innebär att du visst kan instanseria objektet, men mde viss instabilitet. Gör ett test.
test gärna instansiering av new och create objekt oxå så kommer du märka en mätbar skillnad .. Jag tror inte jag sett, hört eller läst någonstns att createobject skulle ha en prestanda fördel över new.. Och anledningen till det är att som nämnt innan, new tar en genväg till clsid och andra viktiga värde som behövs, medan createobject tar den långa mer stabila vägen....Sv: GetObjectContext(Transaction Server)
När du instansierar ett MTS objekt från en baseclient så kan du använda både new och createobject. Själva instansieringen sker på samma sätt vare sig du använder new eller inte, dvs via COM Service Control Manager (SCM). New däremot är snabbare än createobject pga av att progid inte behöver letas upp i registret och översättas till ett clsid i runtime läge vilket är fallet när createobject används. (Precis som Patrik skrev)
//NiklasSv: GetObjectContext(Transaction Server)
Designmässigt skulle jag föredra CreateObject, framförallt för att det är mer flexibelt (tillåter mig att bygga min klient utan att bry mig om min komponent). Men även för att jag inte kan vara säker att de funktioner jag t ex bygger in i klasser i en dll/exe som distribueras till klienten (alltså inte köras i MTS/COM+) alltid kommer att ligga hos klienten. I ett senare läge kanske man bestämmer sig för att flytta in dessa i MTS, och missar man då att ändra från new till createobject så kan det gå illa. Dock kan jag kanske tänka mig att skapa Connections, recordsets och liknande med new, om prestandaskillnaden är nödvändig.
Här är ett litet test jag föreslår:
'' Klient
Dim objA as MyObjA
Set objA = New MyObjA
objA.foo
'' MyObjA, funktionen foo, transaktionell komponent i COM+
Dim ObjCtx as ObjectContext
Dim objB as MyObjB
Set ObjCtx = GetObjectContext()
Set objB = New MyObjB
objB.bar
ObjCtx.SetComplete
'' MyObjB, funktionen bar, transaktionell komponent i COM+
Dim ObjCtx as ObjectContext
Set ObjCtx = GetObjectContext()
''' gör lite arbete, vilket går åt skogen, så vi avbryter den pågående transaktionen
ObjCtx.SetAbort
Vad tror du händer med transaktionen? Går den igeom eller avbryts den? Vilket är det förväntade resultatet?
Ännu värre blir det om MyObjA och MyObjB ligger i samma dll. Då kommer VB-runtime att instansiera MyObjB _UTAN_ att gå genom SCM, därför att New är ett VB-påhitt (som ja, i de fall där de två klasserna ligger i olika dll:er måste gå genom SCM, men inte annars). Detta innebär att MTS/COM+ inte kommer att känna till att MyObjB instansierats.
Ett viktigt sista noterande bara. När jag skrev det här ikväll så kom jag att tänka på att vi alla har missat eller inte tänkt på en sak, nämligen att det vi skrivit dessutom endast gäller COM+, inte MTS. I MTS räcker det inte att använda CreateObject (det ger samma resultat, undantaget prestandamässigt, som att använda new mellan olika dll:er). Istället ska man använda CreateInstance funktionen på ObjectContext objektet:
Dim ObjCtx As ObjectContext
Dim ObjB as MyObjB
Set ObjCtx = GetObjectContext()
Set ObjB = ObjCtx.CreateInstance("MyProject.MyObjB")Sv: GetObjectContext(Transaction Server)
Här är en artikel skriven av Ted Pattison där han diskuterar just instansiering av mts komponenter.
http://msdn.microsoft.com/library/periodic/period99/basics0899.htm
//NiklasSv: GetObjectContext(Transaction Server)
Min diskussion rörde snarare om det var en risk eller 'fel' att använda new i en MTS komponent som skapar en annan MTS komponent. Men då menar vi antagligen allihopa ungefär samma sak.
Japp, det var ungefär vad jag läst (från Ted) i en av hans böcker, samt vad ett seminarie på TechEd gick ut på. Exemplen jag skrev är också baserade på det han predikar.