|
|
This is a known issue (it's been discussed a few other times here on CodeProject as well), but not necessarily a bug (though one could argue it is). There's a lot of information about this on the web. Take a look at this one I grabbed from google: http://weblogs.asp.net/sfurman/archive/2003/03/07/3537.aspx[^].
Basically, it all comes down to precision. The article above has a link to some of the documentation in the .NET Framework SDK that indicates as much. There's also a cludgy work-around if you want to use that instead (using SqlDecimal.Round ).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Thank, it's realy too an output from situations
|
|
|
|
|
Hey
We are doing a Client Server Program and have a problem.
We use:
TcpClient.GetStream
In the client we have a loop that checks the stream with formatter and if there is anything it is translated to a searten obj. When we are starting up an other window(the game) we pason the stream to another while loop in the game.
this works fine, but leter we get som problem, the stream is containing somtehing that we can not translate and that is cousing a error, somthing about instance not set to a object, but it is. The only thing the Server is sending is somthing cald commandobj. we have tryed to translate the stream content to a object and then se whats wrong, but it throws an error when we trying to dezerialize it.
If we look on the Stream during the run before the error we can see that there is a error on Position and lenght in the stream obj.
Now, how can vi flush the stream so its clean? the regular flush is doing nothing?
Best Regards
Jimmy
|
|
|
|
|
|
But will i not lose the connection then?
I need the stream, or do you mean that i shold creat a new stream of the TcpClient? and will this not break the connection?
Best Regards
Jimmy
|
|
|
|
|
I think the connection will be destroyed. So do just
yourStream.Flush();
GC.Collect();
or try to catch exception when your collection will close and then create new in exception handler...
xedom developers team
|
|
|
|
|
Of courcse it does. To not deatroy it do just
yourStream.Flush();
GC.Collect();
or try to catch exception when your collection will close and then create new in exception handler...
xedom developers team
|
|
|
|
|
Okay i will try that.
But when we tested just
MyStream.Flush();
the stream was not cleared, but i hope that GC vill do that. thought that GV just collect unused variables and threads, but i will look it up.
Thanks alot
//Jimmy
|
|
|
|
|
You should almost never call GC.Collect . Instead, just dispose the stream by calling it's Dispose member. This frees-up unmanaged resources and frees memory immediately so that garbage collection isn't even needed for that object. If you force the GC to run, it may take some time as it traverses its references and frees up everything. Let the GC do it's job, and just call Dispose if you don't want the stream anymore.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
It's possible that isnce you have two read/writers talking to the same stream they are corrupting the data. You should either use separate streams or lock against a resource (see the lock keyword for C# or the System.Threading namespace members). Even reading the stream advances the cursor so that if both read the stream at the same time, they get fragmented data. Writing would obviously be a problem if you didn't synchronize access to the stream.
If you look, there's also a ReaderWriterLock class in System.Threading that may be helpful as well, but you must still be mindful of the cursor being repositioned with each read and write to the same stream, even by different callers.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Look..
The Server haves a while loop, in this while loop we got a switch case, Before the switch we got the Dezerialize cod(one row) that Deserialize the stream object to a command object. After this the switch redirect the thread to right case, if it is where we waite on the object that the commad obj was telling us is on the way. It my be a update object or what ever.
When this is done it goes right up to Dezerialize row again there is waits on the next command that arrive.
The Client have something like the Servers loop.
This stream is also used to send obj by other controls in the client and server.
So Far:
We have loggd on to the server with somw clients, the clients can talk and act like thay shold.
When two clients is making a table to play the game on the head form is disposed, but the stream(TcpClient) is sent to the new game form, where we start a thread and goes in to a new loop, a game loop. So far, nor problems.
But now when we have playd we will start up the main form again, and this we have disposed so we start up a brand new and sends over the stream(TcpClient) from the game form and then dispos the game form.
Now we are back in main form. But when we goes in to the while loop that reads the stream for command obj we get an error, and it is this error we are trying to solve.
When we get in to the loop and the Dizerialize(stream) is used, it gives us an exception like: No instance.
But if we use a break point and step we could se that the stream is set to Read = tru, Write = true, and that the data(Long) is containing data that is to big , also there is some error on the position of the stream obj.
we have tryed to read this thing that is in the stream by casting it to simple object and then take a look in the objects type. But we get the error when it is trying to dezirilize it.
We thougt that if there is somthing in the stream buffert that is maby a bit of an old object or somthing we have to get this flushed, so we tested to use Flushed on the stream but the stream is steal containgn error like before.
How could we do ? we have thought of closing the connection and open a new stream, but we have to maintain the connection with the server at al time, otherwize the server will consider the client offline.
And if we got it right, we can not throw the stream and creat a new stream by TcpClient.getstream we will lose the connection with the Server int this case.
Best Regards
Jimmy
|
|
|
|
|
If the position is incorrect, you could reposition the cursor using Stream.Seek (if Stream.CanSeek is true). Based on your comments, however, it's hard to determine exactly what is going on. This would require debugging the app, which you're already doing.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I understand.
we have checkt that the server is not sending any information, so we think that there are som fragments left in the stream.
The only thing that we whant is to clear this buffert and move on, is ther no way to do this? do we realy have to close connection and reopen it?
Reagards
Jimmy
|
|
|
|
|
Normally you could call Stream.SetLength , but the NetworkStream (and casting it won't change the stream Type) always throw a NotSupportedException .
Thinking there'd be fragments doesn't make sense, however. The stream is streamed between the client and server. When you read or write, it always starts with the current cursor location and advanced the amount that you read or write. Everything else is "forgotten".
What you should try is writing a client that will simply buffer what the server sends and writes the content to a log file, as well as makes it available for your application. This wouldn't be a bad idea to leave in the product, either. By "throwing on a switch" (as some applications - including games - have) you could debug communication with the server.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Yes I have lookt at the Stream.SetLength but as you says it will thow a NotSupportedExcepton.
Okay thats good that you explained how the stream workt, we thought that it hade som kinde of buffert that it stores the incoming data in and then work it when it reads the stream.
We have thought of making a sort of log in the Server so that we could see exacly what the server sends and recives from who.
We have alot of timepresser here right now, but i think that this solution(ologg) will solve our problem fastern then fuling around with the flush and things.
Alot of thanks =)
Ragards
Jimmy
|
|
|
|
|
Hi to all,
I want to ask: I wrote a Visual C# application using VS.NET 2003, so it was created to run under Framework v 1.1 and when I try to launch my application on the mashine where VS.NET 2002 installed I just can do it and some exception occurs. The question is how can I create an assembly wich able to launch on Framework 1.0 using VS.NET 2003?
developers team
|
|
|
|
|
VS.NET 2K3 will only build for the .NET Framework 1.1. You could install the .NET Framework 1.1 on the target machine and your app will run without problem.
Now, you could also go into the project properties of your app, Common Properties, General and click on Supported Runtimes. Here you will be able to select which version of the Framework your app will compile against, v1.0, v1.1, or BOTH. But, there's a catch...since v1.0 of the .NET Framework doesn't support certain features v1.1 does and v1.1 has some implementation changes from v1.0, your app might not compile against v1.0 or it will compile, but run differently depending on which framework it's running on.
RageInTheMachine9532
|
|
|
|
|
Thanx. Tommorow I'll try to intall my homework and I hope you solution will help...
www.xedom.com
|
|
|
|
|
Just wanted to add that if you built for 1.0 and ran against a newer framework, you don't need the .config. The framework used is the same or newer than what's referenced in the assembly. The same "gotcha" that Dave mentioned still applies, though, except that deprecated functionality (stuff that doesn't exist in newer frameworks) will cause exceptions to be thrown if you use them, if your assembly even runs. This is much more uncommon, though, as most functionality is usually left in without being changed (functionality may be added to existing classes, but this still works).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Anyone knows how to preview a custom file format with a bitmap in windows explorer?
For example, the 3D Studio file format (file.3ds) is not a gif or bmp or anything. However, if you select it windows explorer, an image preview of the file pops up on the left anyway just as if it were an image file. How is this done?
- Peder -
|
|
|
|
|
This is done via the IExtractImage shell interface. You can find more information about the interface here[^].
If you want to leverage this functionality in your .NET application, see Thumbnail Extraction Using the Shell[^] (something I found quick by googling).
If you have created a document format in .NET and want to support this interface, you must declare this interface in your code like this:
[Guid("BB2E617C-0920-11d1-9A0B-00C04FC2D6C1")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IExtractImage
{
void GetLocation(
[MarshalAs(UnmanagedType.LPTStr), Out] string path,
[MarshalAs(UnmanagedType.U4), In] int pathSize,
[MarshalAs(UnmanagedType.U4), In, Out] ref int priority,
[In] ref Size size,
[MarshalAs(UnmanagedType.U4), In] int RecClrDepth,
[MarshalAs(UnmanagedType.U4), In, Out] ref int flags);
void Extract(IntPtr hBitmap);
} You implement this interface on a class that also exposes a CLSID (Class ID - use the GuidAttribute to explicitly define a CLSID using uuidgen.exe or something). You then register this using regasm.exe from the .NET Framework. The usual regsvr32.exe will not work since an assembly does not export the necessary functions (like DllRegisterServer ).
See Nick's article, Creating a CCW for COM-Enabled, non-.NET Applications[^], for more information on exposing .NET classes as COM components.
You would also have to manually register this CLSID under the PersistentHandler registery key under your extension's registry key. This is how the shell determines if your extension supports thumbnails and determines how to load them (using the CLSID of your class). More information about this is available in the Platform SDK. You can make this easier by attributing a couple static methods with the ComRegisterFunctionAttribute and ComUnregisterFunctionATtribute , which executes code (like your registry code) in addition to the standard stuff that regasm.exe does when it's executed with your assembly as it's command-line parameter.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
This was very informative and interesting! However, I believe I might have expressed myself a tad unprecise. My question was rather how to enable the preview mode on a file type I create myself.
And then, secondly, I suppose the continuation will be to get hold of some image, remove the file headers, and finally embed the image data at some address in the file. Maybe the trick is to make my own derived file class?
- Peder -
|
|
|
|
|
Yes, and what I said is correct. You must define a persistence handler for your document type and register it. Windows Explorer will use this information to generate a thumbnail. The links I gave you provide you with more information about this process.
How your IExtractImage implementation gets the image is entirely up to you. For many Microsoft Office types, a thumbnail is generated when the document is saved and stored in the compound document structure. The persistence handler for those document types extracts that image.
For support videos in Windows Explorer, the IExtractImage implementation extacts the frame so many seconds into the movie and uses that for the thumbmail, which is cached in the Thumbs.db.
Read the Platform SDK for more information. You can also read Mike Dunn's The Complete Idiot's Guide to Writing Shell Extensions - Part I[^], a step-by-step tutorial on writing shell extensions in C++. There is a whole series. This doesn't cover the IExtractImage extension, but should give you a basic idea of what I already covered.
I also gave you the information you need to know how to implement the shell interface in C# and register your .NET assembly as a CCW, or COM-Callable Wrapper, so that it can be used by the shell to use your IExtractImage implementation for your document type.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I've been doing some research for a migration and am having a hard time determining whether it is possible/feasible to call javascript events from a windows form control that's embedded in a web page.
Essentially I'm wanting to use the controls in an activex/applet situation and I want to call a javascript function from the compiled C# control. I would think I could put an event on my control and have the java script 'subscribe' to that event and then I could just fire it as appropriate from within the control. However I'm having a hard time finding a way to do the subscription.
I'd like something like this:
C#:
public class Control1 : UserControl
{
public delegate void SomethingDelegate();
public event SomethingDelegate OnSomethingHappened = null;
..
.. fire the event in the script at some point:
OnSomethingHappened();
..
..
}
Javascript:
<object id="tabControl" name="tabControl" classid="GUIControls.dll#GUIControls.TabControl" width="445" height="250" onsomethinghappened="doSomething" viewastext="">
function doSomething()
{
alert("handled event in javascript");
}
Anybody tried this before? Any help appreciated!
Tim
|
|
|
|
|