|
I did something similar here:
Mediator - a communicator between ViewModels[^]
I.a:
Type unboundWEMType = typeof(WeakEventManager<,>);
Type[] typeArgs = { _sender.Target.GetType(), typeof(EventArgs) };
Type constructedWEMType = unboundWEMType.MakeGenericType(typeArgs);
etc...
It's a pain. 
|
|
|
|
|
Kenneth Haugland wrote:
It's a pain.
Haha, it can be indeed!
|
|
|
|
|
I don't quite understand your problem, if you could make the Generic01 with the code I created above, surely you could get the type from the created element?
|
|
|
|
|
It's for a serializer, I need to recreate the type that was saved.
Not the type that is now.
It might have changed!
|
|
|
|
|
Using fieldType.ToString() would give you System.Collections.Generic.List`1[T] .
If the class had multiple type parameters, it might be important to know which one was used in the type.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Simple!
|
|
|
|
|
Richard Deeming wrote: t might be important to know which one was used in the type.
Ha yes! another bug!
|
|
|
|
|
And in my usual fashion of cobbling together source codes before I have grasped the concepts, I give you this glorious error:
No overload for method 'PassStructIn' takes 4 arguments
The code in question happens to be a call to an unmanaged dll:
class Program
{
public struct Quaternion
{
double w; double x; double y; double z;
}
[DllImport("YLScsDrawing.dll")]
public static extern void PassStructIn(ref Quaternion myQuaternion);
static void Main(string[] args)
{
Program.Quaternion myQuaternion;
Program.PassStructIn(ref myQuaternion);
Thread absoluteThread = new Thread(unused => Program.PassStructIn((double)absW, (double)absX, (double)absY, (double)absZ));
absoluteThread.Start();
Please advise on how to fix this...
Thanks.
|
|
|
|
|
You'd need to know how many arguments are expected. The code complains that there is no method accepting four arguments.
I'd also advise against using a lambda to start a thread.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
You define PassStructIn as taking a single parameter: a reference to a structure you defined above.
Then you try to call it by passing four parameters...and you are surprised you get an error?
Create an instance of the struct and fill in it's fields. Then pass the ref struct to the external method.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
Perhaps showing the code for the dll will help...
using System;
using System.Collections.Generic;
using System.Text;
namespace YLScsDrawing.Drawing3d
{
public struct Quaternion
{
public double X, Y, Z, W;
public Quaternion(double w, double x, double y, double z)
{
W = w; X = x; Y = y; Z = z;
}
}
}
Any suggestions?
|
|
|
|
|
Well... you could always try:
Quaternion quat = new Quaternion ((double)absW, (double)absX, (double)absY, (double)absZ));
Thread absoluteThread = new Thread(unused => Program.PassStructIn(ref quat);
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
The line of code...
Quaternion quat = new Quaternion ((double)absW, (double)absX, (double)absY, (double)absZ);
Brings up the following error.
'Siren.Program.Quaternion' does not contain a constructor that takes 4 arguments
Any other ideas?
|
|
|
|
|
According to your code sample it does:
public struct Quaternion
{
public double X, Y, Z, W;
public Quaternion(double w, double x, double y, double z)
{
W = w; X = x; Y = y; Z = z;
}
}
If that is in a separate DLL, then I'd suggest that you check you are referencing the latest version, and that it compiles without errors.
Because your code samples are referring to different struct names:
Siren.Program.Quaternion in the error message instead of the code sample YLScsDrawing.Drawing3d.Quaternion
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
I have a collection, which uses BindingOperations.EnableCollectionSynchronization. This works great for updating a collection on a background thread using the BackgroundWorker class; however, if the collection is in the process of updating, none of the items properties can be changed elsewhere until the worker has stopped (or so it appears).
The application ends up crashing and I assume this is because only one thread may have access to an object at any given time. If this is correct, how can I prevent the application from crashing?
The issue isn't accessing the collection on the background thread, it's allowing access elsewhere in main thread while collection is updating on background thread.
|
|
|
|
|
I am not sure what your problem is, nor I have use that method myself before, but looking at the documentation:
BindingOperations.EnableCollectionSynchronization Method (IEnumerable, Object) (System.Windows.Data)[^]
I can see that it is used to lock the connection. Hence it might be why you can't access it from another thread hey?
As a side topic, when I do multithread with my ViewModels I usually make sure my VM is thread safe or won't be broken by my code. And I fire all notifications change myself in the UI thread using Dispatcher.BeginInvoke()
In the case of a collection you might want to write your own "ThreadObservableCollection "
|
|
|
|
|
Since I can't see your code or debug it, I can only offer tips.
1. Objects that are instanced and shared are not thread safe. Static code is thread safe. If multiple threads are going to access the same code base, then make that shared "code base" static, if possible.
2. I don't use BGW anymore, if I can help it. I use the Task Parallel Library (TPL -- Google search it). This has saved me from insanity, multiple times.
Is this a possible scenario to use Ansyc programming here?
|
|
|
|
|
Why don't you just use one of the thread-safe collections from the System.Collections.Concurrent namespace?
You also need to be more clear about what you mean by "updating" ... This has some influence on the type of collection best suited.
|
|
|
|
|
The closest to an ObservableCollection I could find was ConcurrentBag, but it doesn't seem to meet all my needs. By 'updating' I simply mean I'm adding items to it on a background thread. Ultimately, I found there is no issue changing the properties of items contained in the collection while items are being added with the current setup; however, the application crashes regardless if items are being added to it when a property in my view model changes, which I don't think has anything to do with threading now.
I'm going to implement my own thread-safe ObservableCollection class just to be safe and go from there. Thanks to everyone who responded!
|
|
|
|
|
You're still not clear: you say you are "simply adding"; then you say you are "changing the properties of the items".
You have said nothing that indicates a "custom" collection.
|
|
|
|
|
Hi All!
thanks to help say, what's the best book about "c# network programming"
Thanks
modified 13-Jul-16 13:25pm.
|
|
|
|
|
|
The problem was in the unmanaged DLL. But I really learnt a great deal about other topics such as BackgroundWorkers and TPL. Thanks all.
=======================
Hello There. I have this small DLL that takes input_name and output_name as parameters. It opens the input file, reads it and produces output file with the specified name after some processing.
I then call this function from C#. First time I call it, it runs fine. But second time around, it throws this exception
<br />
An unhandled exception of System.AccessViolationException occured in CSharpProgram.exe.<br />
Attempted to read or write protected memory.<br />
Here is what I am trying.
[DllImport("MyDll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int Call_Dll_Main(string input, string output);
private void Button_Click(object sender, EventArgs ea)
{
new System.Threading.Thread(new System.Threading.ThreadStart(Call_Dll_Function)).Start()
}
private void Call_Dll_Function()
{
int nResult = Call_Dll_Main(txtInputFile.Text.Trim(), txtOutputFile.Text.Trim());
}
What could be wrong? What am I missing here? Thanks for any input.
modified 14-Jul-16 11:34am.
|
|
|
|
|
Well, the first thing I would do is put those TextBox values you trim into variables before you pass them to the .DLL. The GC will collect those values since they don't have any managed variables or pins holding onto references to them so the GC may be collecting them before your DLL code is finished with them.
Next, it would appear that you're completely ignoring the return code from the C function. I t has nothing to do with the error, but it's something to watch out for.
Any other problems would be in the C code itself, which you didn't show for this function.
|
|
|
|
|
Hi,
I'm assuming you are using WinForms and those textXXXFile objects are Controls, maybe TextBoxes. A Control should only be created and used by a single thread, most often that would be the main or "GUI thread"; violating this rule is bound to give you AccessViolation trouble.
I would recommend you use one (or more if you think you must) BackgroundWorker objects ibstead of bare Threads. A BGW will execute most of its task on a separate thread (which it borrows from the ThreadPool), however it also offers progress and completion events which execute on the main thread (assuming you created the BGW on the main thread) so all AccessViolations would disappear.
If you're unfamiliar with the BGW class, read up on it, I'm pretty sure CP has some fine articles about it.
Note 1: you should get the inputfile before entering the DoWork event.
Note 2: you could reuse the BGW object, or create a new one, that is up to you.
Note 3: there are some BGW properties you have to set true explicitly for it to activate all its goodies!
good luck
|
|
|
|