Error at Watin.Core.Comparer StringComparer class - watin

I am using Watin system in my program.
I get the following error:
ArgumentNullException at Watin.Core.Comparer
StringComparer(string comparisonValue, bool ignoreCase)
Error : Value Cannot be Null(comparisonValue)
But I have no idea that who and when stringcomparer is called,
also I don't know how to debug it.
Here is some of my code.
using (IE browser = new IE(url))
{
Trace.TraceInformation("success to create IE instance.");
int waitSecond = TimeSpan.FromSeconds(30).Seconds;
browser.WaitForComplete(waitSecond);
.........
.........
}
)
Add some ErrorTrace
at WatiN.Core.Comparers.StringComparer..ctor(String comparisonValue, Boolean ignoreCase)
at WitiN.core.DialogHandlers.DialogWatcher.HasDialogSameProcessNameAsBrowserWindow(Window window)
at WatiN.Core.DialogHandlers.DialogWatcher.HandleWindow(Window window)
at WatiN.Core.DialogHandlers.DialogWatcher.Start()
at System.Threading.ThreadHelper.ThreadStart_Context(ojbect state)
at System.Threading.ExecutionContext.Runinternal(exceutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutinoContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutinoContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()

This code works as expected (no exceptions thrown):
using (IE browser = new IE("http://www.google.com"))
{
//Trace.TraceInformation("success to create IE instance.");
int waitSecond = TimeSpan.FromSeconds(30).Seconds;
browser.WaitForComplete(waitSecond);
}
Make sure you are using the latest sources for WatiN and you don't have any other code executing at that time (the exception you are getting if for a DialogWatcher, nothing to do with the code you posted).
Not sure why you've used the .WaitForComplete method like that but that method is called by default internally for each method you run that interacts with a web page. If you want to specify a generic wait time for loading web pages you should use settings for the WatiN object like this:
Settings.WaitForCompleteTimeOut = 30;
using (IE browser = new IE("http://www.google.com"))
{
//Trace.TraceInformation("success to create IE instance.");
browser.WaitForComplete();
}

Related

Blazor: Cannot initialize a ComponentBase more than once

I have a complicated issue when navigation through my Telerik-Blazor-Wizard.
Every Time i want to navigate Back i get this Exception:
Error: System.InvalidOperationException: The render handle is already set. Cannot initialize a ComponentBase more than once.
at Microsoft.AspNetCore.Components.ComponentBase.Microsoft.AspNetCore.Components.IComponent.Attach(RenderHandle renderHandle)
at Microsoft.AspNetCore.Components.RenderTree.Renderer.AttachAndInitComponent(IComponent component, Int32 parentComponentId)
at Microsoft.AspNetCore.Components.RenderTree.Renderer.InstantiateChildComponentOnFrame(RenderTreeFrame& frame, Int32 parentComponentId)
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewComponentFrame(DiffContext& diffContext, Int32 frameIndex)
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewSubtree(DiffContext& diffContext, Int32 frameIndex)
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InsertNewFrame(DiffContext& diffContext, Int32 newFrameIndex)
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForFramesWithSameSequence(DiffContext& diffContext, Int32 oldFrameIndex, Int32 newFrameIndex)
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext& diffContext, Int32 oldStartIndex, Int32 oldEndIndexExcl, Int32 newStartIndex, Int32 newEndIndexExcl)
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.ComputeDiff(Renderer renderer, RenderBatchBuilder batchBuilder, Int32 componentId, ArrayRange`1 oldTree, ArrayRange`1 newTree)
at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment, Exception& renderFragmentException)
at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue()
Note that I´m using a DynamicComponent to render my WizardPages..
#foreach( WizardSeite seite in WizardSeiten )
{
<WizardStep Label="#seite.Title" OnChange="#ReactOnChange">
<Content>
<DynamicComponent #ref="#currentPage" Type="#seite.GetType()" Parameters="#seite.Parameters"></DynamicComponent>
</Content>
</WizardStep>
}
and register the Pages in the ServiceCollection (IoC-Container)..
if( component.BaseType == typeof( WizardSeite ) )
{
// Registriere Wizardseite als Basetyp "WizardSeite"
services.AddTransient( component.BaseType ?? throw new NullReferenceException(), component );
}
If i Navigate back it tries to activate the component, I´m using a custom IComponentActivator that returns the registered Instance of my Wizard-Page.
instance = registeredPages.First( seite => seite.GetType() == componentType );
After that it seems that the component gets initialized twice thus throwing this error.
I know this issue is very specific any help to understand and/or resolve the problem is highly appreciated.
I found the issue!
Inside the IComponentActivator constructor i load the registered Pages once (into a list called registeredPages). The problem with this is that if the render tree gets refreshed it tries to initialize the component but gets the same instance of it. That leads to the exception above.
The solution: I register the components as Transiants thus every time i call GetService i get a new instance of the requested type. If i refresh registeredPages it always has a fresh component that can be initialized:
registeredPages = ServiceProvider.GetServices<WizardSeite>();
instance = registeredPages.First( seite => seite.GetType() == componentType );

Execute MVVMCross value converter logic on UI thread

I am working on a Xamarin.iOS project, and have a MVVMCross value converter that takes a file extension string and returns the corresponding file icon as an UIImage.
This converter is used in a file list. I found that when I'm scrolling the list, as soon as the MvxTableViewCell is recycled, the UI converter is often invoked in the background thread for the recycled cell, making my code to throw an error complaining calling a UIKit method from a background thread.
It looks like in the latest version of MVVMCross, the old IMvxMainThreadDispatcher.RequestMainThreadAction method is obsolete. The documentation recommends to use IMvxMainThreadAsyncDispatcher.ExecuteOnMainThreadAsync method.
However, this method returns a Task with no generic type. This obviously can't work with the Convert method of the value converter which expects the UIImage.
Is there a way to configure MVVMCross to always invoke the converter on UI thread?
Update:
Take the following code example:
public class FileIconConverter : MvxValueConverter<string, UIImage>
{
protected override UIImage Convert(string fileExtension, Type targetType, object parameter, CultureInfo culture)
{
// When this is called, it could be in a background thread.
// Since UIDocumentInteractionController.FromUrl requires to be called
// on the UI thread, it would throw the UIKitThreadAccessException.
return UIDocumentInteractionController.FromUrl(NSUrl.FromFilename("/tmp/generic" + fileExtension)).Icons[0];
}
}
Since you have not added any code here all I can do is give you a bit of speculative advice.
What you can do is use the InvokeOnMainThread method of Xamarin.iOS
When you check the Xamarin.iOS documentation on Working with the UI Thread in Xamarin.iOS
You can see that you use this method to make the changes that are supposed to be made on the UI
InvokeOnMainThread ( () => {
// manipulate UI controls
});
Update
First of all, if you check the code for IMvxMainThreadDispatcher.RequestMainThreadAction at the MvvmCross's Git it is internally calling the same API!
So what you can do to your existing code is something like
public class FileIconConverter : MvxValueConverter<string, UIImage>
{
protected override UIImage Convert(string fileExtension, Type targetType, object parameter, CultureInfo culture)
{
UIImage image;
IMvxMainThreadAsyncDispatcher.ExecuteOnMainThreadAsync(()=>{
image=UIDocumentInteractionController.FromUrl
(NSUrl.FromFilename("/tmp/generic" + fileExtension)).Icons[0];
});
return image;
}
}

Using native plugin with callbacks in Unity editor (OS X)

I have a native plugin that has callbacks back to the C# code. This is how the callbacks are setup:
C# Side (Unity):
public delegate void Callback(int value);
[DllImport("NativePlugin")]
public static extern void setup_callback(Callback callback);
[MonoPInvokeCallback(typeof(Callback))]
private static void OnCallback(int value)
{
Debug.Log("Callback called with value: " + value);
}
void Start()
{
setup_callback(OnCallback);
}
The Objective-C side (with C wrapper so you'd be able to call it from C#):
typedef void(*Callback)(int);
Callback _callback = NULL;
void setup_callback(Callback callback)
{
_callback = callback;
}
void on_something_happened(int value)
{
if(_callback)
_callback(value);
}
Now, most of the time the above code works ok, and I receive the correct values in Unity. But sometimes when I make changes to any one of my C# scripts, Unity crashes with this:
Exception Type: EXC_BAD_ACCESS (SIGABRT)
Exception Codes: KERN_INVALID_ADDRESS at 0x00000000ffffffa9
Exception Note: EXC_CORPSE_NOTIFY
Looking at Unity's Editor logs I found out that when I make changes to a C# script it recompiles Assembly-CSharp.dll and reloads it togheter with some other C# assemblies. So that made me think that this might cause the pointer saved in the native plugin to now point to an invalid address (because Assembly-CSharp.dll is now probably in a different address space). Note that it does not happen every time the dll gets reloaded, is it possible that it gets reloaded to the exact same address space sometimes?
Can I get an event from Unity when the editor reloads the DLL and then re-register the callbacks (assuming that this is the real problem)? Is this even the correct way to setup a callback from native code?

Linq to SharePoint throwing null reference exception

In our SharePoint 2010 project we are using Linq to SharePoint to get a list of ConfigurationItems. On our testing environments we never had issues fetching data from this list. On our production environment we are now sometimes (we cannot find a pattern right now) getting a null reference exception when looping through the items in the list.
Below is the exception whe are getting thrown from the Linq to SharePoint code:
Object reference not set to an instance of an object. StackTrace:
at Microsoft.SharePoint.Linq.FieldRef.GetHashCode()
at Microsoft.SharePoint.Linq.FieldRef.FieldRefEqualityComparer.GetHashCode(FieldRef obj)
at System.Linq.Set`1.InternalGetHashCode(TElement value) at System.Linq.Set`1.Find(TElement value, Boolean add) at System.Linq.Enumerable.d__7a`1.MoveNext()
at System.Linq.Buffer`1..ctor(IEnumerable`1 source) at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source) at Microsoft.SharePoint.Linq.SelectMappingInfo.GetDistinctMappedFields()
at Microsoft.SharePoint.Linq.Rules.PushDownProcessor.SelectWithInfoOp.PushDownSelect(Context ctx)
at Microsoft.SharePoint.Linq.Rules.PushDownProcessor.SelectWithInfoOp.Process(Context ctx)
at Microsoft.SharePoint.Linq.Rules.GuardedRule`4.c__DisplayClass7.b__6(TSourceBase src, TContext ctx)
at Microsoft.SharePoint.Linq.Rules.RewriteRule`2.Apply(TNode src, TContext ctx) at Microsoft.SharePoint.Linq.Rules.CacheRule`3.Apply(TSource src, TContext ctx)
at Microsoft.SharePoint.Linq.Rules.PushDownProcessor.b__0(Expression e, Context ctx)
at Microsoft.SharePoint.Linq.Rules.ChildRule`2.Apply(TNode src, TContext ctx) at Microsoft.SharePoint.Linq.Rules.PushDownProcessor.b__3(Expression e, Context ctx)
at Microsoft.SharePoint.Linq.Rules.RewriteRule`2.Apply(TNode src, TContext ctx) at Microsoft.SharePoint.Linq.Rules.CacheRule`3.Apply(TSource src, TContext ctx)
at Microsoft.SharePoint.Linq.SPLinqProvider.Rewrite(Expression expression, List`1& assumptions)
at Microsoft.SharePoint.Linq.SPLinqProvider.RewriteAndCompile[T](Expression expression, List`1& assumptions)
at Microsoft.SharePoint.Linq.LinqQuery`1.GetEnumerator()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Common.Configuration.ConfigurationRepository.GetConfiguration(String siteUrl) InnerException:
Source: Microsoft.SharePoint.Linq TargetSite: Int32 GetHashCode()
And here the code we use in our GetConfiguration method.
using (SpDataContext dataContext = new SpDataContext(siteUrl))
{
result = new ConfigurationModel()
{
Configurations = (from item in dataContext.GasportConfiguration
select new ConfigurationItem()
{
Key = item.Key,
Value = item.Value,
Environment = (Environment)Enum.Parse(typeof(Environment), item.Environment.ToString(), true)
}).ToList()
};
}
Anyone having ideas on how to track this down to what's causing this exception?
UPDATE 31-05-2011:
We found a pattern in which way we can reproduce this behaviour on our production environment. And also on our test environment we had this issue too, from which we extracted some Crash Dump files by using AdPlus.
We see this behaviour occuring after the application pool is recycled. The only way to fix this error is to perform a full IISreset.
In the crashdump analysis I found an exception message that states:
Exception Code: 0xC0000005
Exception Information: The thread tries to read from or write to a virtual address for which it does not have the appropriate access.
Hope that someone could give me some more information on this exception?
Unfortunately we haven't found a solution for this issue and decided to move away from LINQ to SharePoint. For a few lists we have changed it to SQL tables (Linq to SQL) and for the SharePoint Lists we moved back to CAML.
In our project we use Linq to Sharepoint heavily and were having this problem come up intermittently, and only on production. The only thing that seemed to work when it happened was an IISReset.
We dug into the problem a little deeper and still don't know what causes it to happen. But we found that you can automatically fix it when it occurs by clearing some private cache variables. Here's our code:
public static class SharePointless
{
public static void Reset()
{
var assembly = Assembly.GetAssembly(typeof(EntityList<>));
var providerType = assembly.GetType("Microsoft.SharePoint.Linq.SPLinqProvider");
var singleton = providerType.GetField("Singleton", BindingFlags.Static | BindingFlags.Public);
if (singleton == null) throw new Exception("Expected field doesn't exist in SPLinqProvider");
singleton.SetValue(null, Activator.CreateInstance(providerType));
var itemMappingInfoType = assembly.GetType("Microsoft.SharePoint.Linq.SPItemMappingInfo");
var cachedMappings = itemMappingInfoType.GetField("cachedMappings", BindingFlags.Static | BindingFlags.NonPublic);
if (cachedMappings == null) throw new Exception("Expected field doesn't exist in SPItemMappingInfo");
cachedMappings.SetValue(null, null);
}
}
Example usage:
public static void MyMethod(bool retry)
{
try
{
using (var db = new MyDataContext())
{
DoStuff(db);
}
}
catch (NullReferenceException ex)
{
if (retry && ex.StackTrace.Contains("FieldRef.GetHashCode"))
{
SharePointless.Reset();
MyMethod(false);
}
}
}
In our case we also had the catch code send us an email so we knew that the problem happened and the fix worked.
We came across the same thing. The following steps solved it:
Regeneration of the dataContext class via SPMetal on the server causing the problem
Reapply the class to your project and rebuild
Redeploy the solution (copying the DLL to the GAC worked)

Subscription to DTE events doesn't seem to work - Events don't get called

I've made an extension inside a package and I am calling the following code (occurs when a user presses a button in the toolbar):
DocumentEvents documentEvents = (DTE2)GetService(typeof(DTE));
_dte.Events.DebuggerEvents.OnEnterBreakMode += DebuggerEvents_OnEnterBreakMode;
_dte.Events.DebuggerEvents.OnEnterDesignMode += DebuggerEvents_OnEnterDesignMode;
_dte.Events.DebuggerEvents.OnContextChanged += DebuggerEvents_OnContextChanged;
_dte.Events.DocumentEvents.DocumentSaved += new _dispDocumentEvents_DocumentSavedEventHandler(DocumentEvents_DocumentSaved);
_dte.Events.DocumentEvents.DocumentOpened += new _dispDocumentEvents_DocumentOpenedEventHandler(DocumentEvents_DocumentOpened);
void DocumentEvents_DocumentOpened(Document Document)
{
}
void DocumentEvents_DocumentSaved(Document Document)
{
}
void DebuggerEvents_OnEnterBreakMode(dbgEventReason Reason, ref dbgExecutionAction ExecutionAction)
{
}
void DebuggerEvents_OnContextChanged(Process NewProcess, Program NewProgram, Thread NewThread, StackFrame NewStackFrame)
{
}
private void DebuggerEvents_OnEnterDesignMode(dbgEventReason reason)
{
}
The first and the major problem is that the subscription to the event doesn't work. I've tried:
Opening new documents
Detaching from debug (thus supposedly triggering OnEnterDesignMode
Saving a document
None of these seem to have any effect and the callback functions were never called.
The second issue is that the subscription to the event line works USUALLY (the subscription itself, the callback doesn't work as described above) but after a while running the subscription line, e.g:
_dte.Events.DebuggerEvents.OnEnterBreakMode -= DebuggerEvents_OnEnterBreakMode;
Causes an exception:
Exception occured!
System.Runtime.InteropServices.InvalidComObjectException: COM object that has been separated from its underlying RCW cannot be used.
at System.StubHelpers.StubHelpers.StubRegisterRCW(Object pThis, IntPtr pThread)
at System.Runtime.InteropServices.UCOMIConnectionPoint.Unadvise(Int32 dwCookie)
at EnvDTE._dispDebuggerEvents_EventProvider.remove_OnEnterDesignMode(_dispDebuggerEvents_OnEnterDesignModeEventHandler A_1)
Any ideas will be welcome
Thanks!
Vitaly
Posting an answer that I got from MSDN forums, by Ryan Molden, in case it helps anyone:
I believe the problem here is how the
CLR handles COM endpoints (event
sinks). If I recall correctly when
you hit the
_applicationObject.Events.DebuggerEvents
part of your 'chain' the CLR will
create a NEW DebuggerEvents object for
the property access and WON'T cache
it, therefor it comes back to you, you
sign up an event handler to it (which
creates a strong ref between the
TEMPORARY object and your object due
to the delegate, but NOT from your
object to the temporary object, which
would prevent the GC). Then you don't
store that object anywhere so it is
immediately GC eligible and will
eventually be GC'ed.
I changed the code to store DebuggerEvents as a field and it all started to work fine.
Here is what #VitalyB means using code:
// list where we will place events.
// make sure that this variable is on global scope so that GC does not delete the evvents
List<object> events = new List<object>();
public void AddEvents(EnvDTE dte)
{
// create an event when a document is open
var docEvent = dte.Events.DocumentEvents;
// add event to list so that GC does not remove it
events.Add(docEvent );
docEvent.DocumentOpened += (document)=>{
Console.Write("document was opened!");
};
// you may add more events:
var commandEvent = dte.Events.CommandEvents;
events.Add(commandEvent );
commandEvent.AfterExecute+= etc...
}

Resources