Fail to call CreateAdapterForPath from time to time

Bug reports.
chhb_fancy
Posts: 14
Joined: Thu Aug 14, 2008 2:09 am

Fail to call CreateAdapterForPath from time to time

Post by chhb_fancy » Wed Mar 04, 2009 2:06 am

My code is as following:

public class FormRepository : RepoGenBaseFolder
{
public FormRepository(String name, int handle, RepoGenBaseFolder appFolder)
: base(name, "/form[@handle='" + handle + "']", appFolder, 5000, true)
{
}

public FormRepository(String name, int handle)
: this(name, handle, null)
{
}

public Ranorex.Form Self
{
get {
return CreateAdapterForPath<Ranorex.Form>("Self", "", 5000, null);
}
}

public T CreateAdapterForPath<T>(String itemName, String path, int searchTimeout)
where T:Adapter
{
return base.CreateAdapterForPath<T>(itemName, path, searchTimeout, null);
}
}

the following is calling:

FormRepository rep = new FormRepository("Form", handle);

Ranorex.Form form = rep.Self; //here got error as below sometimes

Exception stack:

System.NullReferenceException: Object reference not set to an instance of an object.
at Ranorex.Core.Element.GetFromAttributeCache(String name, Object& value)
at Ranorex.Core.Element.GetAttributeValue(String name)
at Ranorex.Core.Path.AttributeValueOperand.GetStringValue(Element node, String nodeTestName)
at Ranorex.Core.Path.ComparisonPredicate.Evaluate(Element element, String nodeTestName)
at Ranorex.Core.RxPath.AddFilteredNodeTestAndPredicates(Element element, LocationStep step, IList`1 targetList)
at Ranorex.Core.RxPath.collectAxis(LocationStep step, Element self, IList`1 elements, Boolean quitOnFirstGoodNode)
at Ranorex.Core.RxPath.Apply(Element startElement, IDataProvider dataProvider, Duration timeout, Boolean findSingle)
at Ranorex.Core.Element.FindSingle(RxPath path, Duration timeout)
at Ranorex.Core.Repository.RepoGenBaseFolder.GetFolderElement(Boolean& isCached)
at Ranorex.Core.Repository.RepoGenBaseFolder.CreateAdapterForPath[T](String itemName, String path, Duration searchTimeout, Nullable`1 useEnsureVisible)

For preview4977, I hadn't never gotten this error.
For RC1, 2.0, 2.0.1, I got this error sometimes.

Any help is very appreciated.

User avatar
Support Team
Site Admin
Site Admin
Posts: 11709
Joined: Fri Jul 07, 2006 4:30 pm
Location: Graz, Austria

Post by Support Team » Wed Mar 04, 2009 4:15 pm

I cannot reproduce the issue, but it might be a problem with our caching layer.

1) Does your test application access Ranorex objects from more than one thread ?

2) Try enclosing the code which throws the exception in a

using (new CacheSessionContext())
{
...
}

section and check if the problem persists (as a possible workaround; this is not necessary under normal circumstances).

Michael
Ranorex Team

chhb_fancy
Posts: 14
Joined: Thu Aug 14, 2008 2:09 am

Post by chhb_fancy » Mon Mar 16, 2009 9:36 am

Yes, my test application needs to access Ranorex objects from more than one thread.

I have changed the code as below:

public Ranorex.Form Self
{
get {
using (new CacheSessionContext())
{
return CreateAdapterForPath<Ranorex.Form>("Self", "", 5000, null);
}
}
}

public T CreateAdapterForPath<T>(String itemName, String path, int searchTimeout)
where T:Adapter
{
using (new CacheSessionContext())
{
return base.CreateAdapterForPath<T>(itemName, path, searchTimeout, null);
}
}

but sometimes I still got the error.

User avatar
Support Team
Site Admin
Site Admin
Posts: 11709
Joined: Fri Jul 07, 2006 4:30 pm
Location: Graz, Austria

Post by Support Team » Mon Mar 16, 2009 4:10 pm

This looks like a race condition between the threads accessing the FormRepository. Could you please try synchronizing the access to the whole repository? I.e. acquire a lock to a static lockObject variable whenever you access a repository from two or more threads. E.g. you could just replace the using (new CacheSessionContext()) by a lock (lockObject) statement where lockObject is a static object variable:

Code: Select all

static object lockObject = new object();
...
public T CreateAdapterForPath<T>(String itemName, String path, int searchTimeout) 
where T:Adapter 
{
    lock (lockObject)
    { 
        return base.CreateAdapterForPath<T>(itemName, path, searchTimeout, null); 
    }
}
Regards,
Alex
Ranorex Support Team