ArrayTypeMismatchException in copy constructor - c#

I rarely get an ArrayTypeMismatchException in my program:
public Map(Map otherMap)
{
var cpyArr = new char[otherMap.PlayingField.GetLength(0), otherMap.PlayingField.GetLength(1)];
Array.Copy(otherMap.PlayingField, cpyArr, otherMap.PlayingField.Length);
PlayingField = cpyArr;
var cpyTrans = new List<Transition>();
foreach (var item in otherMap.Transitions)
{
cpyTrans.Add(new Transition(item.X1, item.Y1, item.D1, item.X2, item.Y2, item.D2));
}
Transitions = cpyTrans;
}
The PlayingField property is a twodimensional char array.
Here is the output:
Unhandled Exception: System.ArrayTypeMismatchException: (Types:
source=System.Char; target=System.Char)
The strange thing is that this doesn't happen all the time, just occasionally.
The exception gets thrown at Array.Copy, but the error clearly states that the types actually do match.
How do I fix this?
EDIT: I should also add that the program is being compiled using the current Mono version and run on Linux. But I couldn't reproduce the error on my testing systems. The program is supposed to run on a server system which I sadly have neither access to, nor do I have any information about except that it also runs linux.

Related

Runtime casting of COM objects in C#

I am working on a application which needs to communicate via COM interface with multiple CAD applications (not in the same time). I want to have nice and reusable code, but I came across problems with type casting of COM objects when I made generic application handle getter method.
What I tried so far:
This is the attempt I would like the most if it worked.
public static TCadAppType CadApp<TCadAppType>()
{
dynamic cadApp = default(TCadAppType);
//Here under Dynamic View/Message there is already an error
// Message = "Element not found. (Exception from HRESULT: 0x8002802B (TYPE_E_ELEMENTNOTFOUND))"
// cadVersion.Value evaluates to "SldWorks.Application"
cadApp = (TCadAppType)Marshal.GetActiveObject(cadVersion.Value);
//Following 2 lines of code are for testing purposes only, i am testing with Solidworks API
AssemblyDoc Assembly;
//The exception is thrown when I try to access some method from the Solidworks API
Assembly = (AssemblyDoc)cadApp.OpenDoc6("some parametras...");
}
Attempt using Convert class
// Another attempt using Convert class
public static TCadAppType CadApp<TCadAppType>()
{
dynamic cadApp = default(TCadAppType);
// cadVersion.Value evaluates to "SldWorks.Application"
cadApp = Marshal.GetActiveObject(cadVersion.Value);
cadApp = Convert.ChangeType(cadApp, typeof(SldWorks.SldWorks));
// Exception is thrown with the following message:
// Message = "Object must implement IConvertible."
}
I really thought that I am on the right track, since there is an article on Microsoft Docs website explaining how dynamic can help you with com interopt: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/types/using-type-dynamic#com-interop
Any ideas how I can do this runtime casting a keep my code as reusable as possible?
My software setup:
Win 10
Project is targeted for .NET 4.7.2
First Tests are with Solidworks 2019
Turns out that the my coding attempt 1 was valid c# code indeed.
I tried it using with Autodesk Inventor, and it works.
So the only thing left for me is to conclude that this is some bug from Solidworks and their COM interfacing.
Thank you Optional Option for your interest in the topic.

CSCore: access violation when listening to audio session events

I'm just getting started with CSCore, and getting back to C# after a lot of C++. Here's a test program that enumerates the audio sessions of the default audio session manager, and attaches an empty event handler to each one:
using System;
using CSCore.CoreAudioAPI;
class Program
{
static void Main(string[] args)
{
using (var enumerator = new MMDeviceEnumerator())
using (var device = enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia))
using (var sessionManager = AudioSessionManager2.FromMMDevice(device))
using (var sessionEnumerator = sessionManager.GetSessionEnumerator())
{
foreach (var control in sessionEnumerator)
{
var control2 = control.QueryInterface<AudioSessionControl2>();
RegisterAudioSession(control2);
}
}
Console.WriteLine("Waiting...");
Console.ReadKey();
}
static void RegisterAudioSession(AudioSessionControl2 session)
{
if (session.Process != null)
{
var events = new AudioSessionEvents();
session.RegisterAudioSessionNotification(events);
}
}
}
I would expect to be able to change the volume of my computer while this program is running without any problems. If you try this, however, the program crashes with an access violation in native code. Here's the stack trace:
> AudioSes.dll!CLockedList<ATL::CComPtr<IAudioSessionEvents>,0,1>::ForEachEntry() Unknown
AudioSes.dll!CAudioSessionControl::OnAudioSessionEvent() Unknown
AudioSes.dll!CAudioSessionControl::CAudioSessionNotificationDelegator::OnMediaNotification(struct MEDIA_NOTIFICATION_BLOCK *) Unknown
MMDevAPI.dll!CMediaNotifications::OnMediaNotificationWorkerHandler(struct _TP_CALLBACK_INSTANCE *) Unknown
MMDevAPI.dll!CMediaNotifications::MediaNotificationWorkerHandler(struct _TP_CALLBACK_INSTANCE *,void *) Unknown
ntdll.dll!TppSimplepExecuteCallback() Unknown
ntdll.dll!TppWorkerThread() Unknown
kernel32.dll!#BaseThreadInitThunk#12() Unknown
ntdll.dll!__RtlUserThreadStart() Unknown
ntdll.dll!__RtlUserThreadStart#8() Unknown
The crash does not occur if you remove the call to RegisterAudioSessionNotification.
The crash still occurs if you register a non-empty event handler.
I tried moving Console.ReadKey(); into the using block in case a necessary resource was being disposed, but the failure persisted.
I searched all over the place for an explanation and solution. There are no relevant open issues on CSCore's github page. I read somewhere that crashes in native code are often caused by incorrect signatures in wrapper assemblies. I compared all of the methods on CSCore's IAudioSessionEvents to the native IAudioSessionEvents methods (enumerated here) but found no obvious discrepancies.
This Firefox bug is the only reference I found online to this particular stack trace, and it has been resolved. Apparently it was resolved in Flash Player 19.0.0.159, but as far as I know that source isn't available for perusal.
Am I overlooking an error in my code, or is this a bug in CSCore?
Turns out this crash occurs if the target platform is 32-bit (or in my case, "Any CPU" but running in the 32-bit VS process). Switching to a 64-bit target platform fixed it for me

Unknown exception at declaration and initalisation of a Class

The main Problem is completely different, please skip to the Edit
I have an exception of an unknown type which doesn't even get thrown properly. Following Code provides the Context:
MMDataAccess.InitDemoDB();
MMDataAccess.InitInternalDB();
MMDataAccess.InitMaintDB();
try
{
SQLiteToDBLib sqltdbl = new SQLiteToDBLib();
sqltdbl.WriteToSQLite();
}
catch(Exception ex)
{
string message = ex.Message;
}
These are the very first lines of my first Activity in my app. The first 3 lines belong to my very own implementation of an in-memory database and are behaving nicely. The problem rises with the next two lines inside the try-block. The declaration and initalistation of the sqltdbl variable never happens. The constructor of SQLiteToDBLib looks like this:
public SQLiteToDBLib()
{
msc = new MSConnection();
}
The MSConnection class doesn't even have a constructor (except for the default one of course).
As you can see i've tried to catch any exceptions, but without success. everything i can figure out is, that a exception is thrown because of the debugger going into the catch section while ignoring everything that has to do with "ex". Without breakpoints everything seems fine. Just without the call to WriteToSQLite which should create a .sqlite file on the external Memory.
What can I do to resolve this error? Is there anything i can catch except the default Exception?
Edit:
After some testing with commented code something interresting happened. I could step into commented code. Well not exactly the commented code, but the code that was there before my changes. Visual Studio somehow shows me the things, that are changed in the file, but is compiling the old code. Up to now i tried to rebuild, clean and build the project in various combinations, unload and reload the project, Restart Visual Studio and restart Windows. Nothing has changed so far. I Will now proceed to create a new .cs File With the exact same Code. I'm working with VS 2013 Community
add static constructor to your SQLiteToDBLib class and perform all static objects initialization in it:
static SQLiteToDBLib()
{
// initialize static members here
}
If this doesn't give you a clue, try enabling CLRE exceptions-break in visual-studio:
DEBUG
Exceptions
Check the 'Common Language Runtime Exceptions' option (under the 'Thrown' column)
Press OK
Restart your app and try again

Executable fails with weird exception

I am using ILMerge and Quartz.NET in a C# .NET 4.0 Windows Service application. The app runs fine without using ILMerge, but now that we're nearing shipping release, I wanted to combine all DLLs into a single executable.
Problem is, that ILMerge seems to work fine, but when I run the combined executable, it throws this exception:
Unhandled Exception: Quartz.SchedulerException: ThreadPool type 'Quartz.Simpl.SimpleThreadPool' could not be instantiated. ---> System.InvalidCastException: Unable to cast object of type 'Quartz.Simpl.SimpleThreadPool' to type 'Quartz.Spi.IThreadPool'.
at Quartz.Util.ObjectUtils.InstantiateType[T](Type type) in :line 0
at Quartz.Impl.StdSchedulerFactory.Instantiate() in :line 0
--- End of inner exception stack trace ---
at Quartz.Impl.StdSchedulerFactory.Instantiate() in :line 0
at Quartz.Impl.StdSchedulerFactory.GetScheduler() in :line 0
Does anyone have any idea why this is? I have been wasting over 4 hours already and I can't figure it out. If I don't combine with ILMerge, then everything runs fine (with the Quartz.dll and Common.Logging.dll in the same directory).
I'm sure someone must have tried packaging Quartz.net up like this before, any ideas?
Disclaimer: I don't know Quartz.NET at all, although I spent some time struggling with ILMerge. When I finally understood its limitations... I stopped using it.
ILMerge'd application tends to have problems with everything which contains the word "reflection".
I can guess (I've never used Quartz.NET) that some classes are resolved using reflection and driven by configuration files.
Class is not only identified by its name (with namespace) but also by assembly it is coming from (unfortunatelly it doesn't get displayed in exception message).
So, let's assume you had (before ILMerging) two assemblies A (for you Application) and Q (for Quartz.NET).
Assembly 'A' was referencing assembly 'Q' and was using a class 'Q:QClass' which was implementing 'Q:QIntf'.
After merging, those classes became 'A:QClass' and 'A:QIntf' (they were moved from assembly Q to A) and all the references in code has been replaced to use those (completely) new classes/interfaces, so "A:QClass" is implementing "A:QIntf" now.
But, it did not change any config files/embedded strings which may still reference "Q:QClass".
So when application is reading those not-updated config files it still loads "Q:QClass" (why it CAN find it is a different question, maybe you left assembly 'Q' in current folder or maybe it is in GAC - see 1).
Anyway, "Q:QClass" DOES NOT implement "A:QIntf", it still implements "Q:QIntf" even if they are binary identical - so you can't cast 'Q:QClass' to 'A:QIntf'.
The not-ideal-but-working solution is to "embed" assemblies instead of "merging" them. I wrote a open-source tool which does it (embedding instead of merging) but it is not related to this question. So if you decide to embed just ask me.
You can test it by removing (hiding, whatever works for you) every single instance of Q.dll on your PC. If I'm right, the exception should say now 'FileNotFound'.
You could try creating your own ISchedulerFactory and avoid using reflection to load all of your types.
The StdSchedulerFactory uses this code to creat a threadpool. It's where your error is happening and would be the place to start looking at making changes:
Type tpType = loadHelper.LoadType(cfg.GetStringProperty(PropertyThreadPoolType)) ?? typeof(SimpleThreadPool);
try
{
tp = ObjectUtils.InstantiateType<IThreadPool>(tpType);
}
catch (Exception e)
{
initException = new SchedulerException("ThreadPool type '{0}' could not be instantiated.".FormatInvariant(tpType), e);
throw initException;
}
The ObjectUtils.InstantiateType method that is called is this one, and the last line is the one throwing your exception:
public static T InstantiateType<T>(Type type)
{
if (type == null)
{
throw new ArgumentNullException("type", "Cannot instantiate null");
}
ConstructorInfo ci = type.GetConstructor(Type.EmptyTypes);
if (ci == null)
{
throw new ArgumentException("Cannot instantiate type which has no empty constructor", type.Name);
}
return (T) ci.Invoke(new object[0]);
}
Right after this section in the factory, datasources are loaded using the same pattern and then the jobs themselves are also loaded dynamically which means you'd also have to write your own JobFactory. Since Quartz.Net loads a bunch of bits and pieces dynamically at runtime going down this road means you might end up rewriting a fair amount of things.

uncatchable exception from unreachable code

I run into a very strange problem in my C# 2.0 WinForms app and I'm not even sure if its worth asking SO, because the problem occurs in a strange setup and I don't think that you could reproduce it without my sources, but I'm totally out of ideas.
I have a Form with a TreeView on the left and an ListView on the right. The TreeView shows all available files and subfolders from a specific folder(which contains documents i need for my app). If a Folder is selected the ListView shows all files and subfolders from the selected folder. At startup I populate the TreeView form the folder and after that I select the first TreeNode by code(in my case it's an folder). After that the Content of the TreeView looks like this:
-folder
-file1
-file2
Selecting the folder triggers the AfterSelecedEvent of the TreeView. Because a folder was selected I populate the ListView using the following methode:
private void fillOverview(FAFolder folder)
{
lv_overview.Items.Clear();
ListViewItem item;
foreach (FAFile file in folder.sortedContent)
{
if (file is FAFolder)
{
item = new ListViewItem(file.Name, "Folder"); //exception got thrown here
}
else
{
item = new ListViewItem(file.Name, file.Name);
}
item.Tag = file;
lv_overview.Items.Add(item);
}
}
As you can see there is no subfolder, so the line item = new ListViewItem(file.Name, "Folder"); should never be touched in this setup, but every now and then a NullReferenceException got thrown. If I wrap this line with try/catch the exception got thrown inside the catch block. I tried checking everything if it's null or not, but ther were no nullreferences. Or if I add a MessageBox right before this line the exceptions got still thrown and no MessageBoxpops up. This brings me to the conclusion that the execption stacktrace is wrong and/or this exceptions comes from an other Thread or something like that.
I'm a very optimistic person and I know how clever the SO community can be, but I don't think that anybody can point out what the problem is. So what i'm actuallly looking for are hints and advices how i could find and debug the cause of this strange behavior.
EDIT:
internal abstract class FAFile
{
internal string Name;
internal readonly FAFolder Parent;
internal FAFile(FAFolder parent)
{
this.Parent = parent;
}
}
internal sealed class FAFolder : FAFile
{
internal readonly IDictionary<string, FAFile> Content = new Dictionary<string, FAFile>();
internal FAFolder(FAFolder parent, string name) : base(parent)
{
this.Name = name;
}
}
internal sealed class FADocument : FAFile
{
public readonly string Path;
public FADocument(FAFolder parent, string path): base(parent)
{
this.Path = path;
this.Name = System.IO.Path.GetFileNameWithoutExtension(path);
}
}
Have you tried an null check on folder.sortedContent ?
Usually ReSharper will prompt me that something like that should have a null check.
If you want to be sure, add the following line to your code, above the foreach loop:
if (folder.sortedContent == null) throw new Exception("It was null, dangit!");
On the line you mention:
item = new ListViewItem(file.Name, "Folder")
the only thing that can cause a NullReferenceException is if file is null (unless the exception is being thrown from within the ListViewItem constructor itself).
You don't provide the code for folder.sortedContent so I can't tell - but is it possible that one of the elements in this collection might be null under certain circumstances?
If the ListViewItem constructor is throwing the exception then you will need to use Reflector to look at the code, or download the reference source.
A co-worker of mine just found the answer(probably). I use a Thread to load the ImageList to the ListView from the HDD and this thread sometimes freezes and if i assign a ImageKey it fails. That's no answer why the exception is uncatchable or why it's thrown at this (unreachable) line. But i strongly belive that this is the cause of the problem.
That line is not unreachable. Because FAFolder derives from FAFile, it is possible that 'file is FAFolder' will return true.
However, that would imply that file is not null, unless it is being changed by another thread.
Edit: file can't be changed by another thread as it's a local reference. Can you provide a stack trace for the exception? This one has me intrigued now.
I just cannot help wondering is the FAFolder contain a '.' or a '..' for parent and subdirectory? and the sorting breaks as a result?
This answer will be edited accordingly if this turns out to be untrue?
Hope this helps,
Best regards,
Tom.
Is this exception reproducible on demand?
Can you show the the stack trace of the exception?
What other threads are running when the exception is thrown?
In general, there are two ways to debug this type of stuff. The first way is so-called "scientific" debugging:
Devise a theory to explain observed behaviour.
Devise an experiment to test the theory.
Run the experiment and observe the results.
The second way is by stripping-down the actual code piece by piece until the exception is no longer triggered. Then you have a significant clue for further investigation.
This brings me to the conclusion that the execption stacktrace is wrong....
It's usually easier to start by assuming that the problem is in your own code.

Categories