by Phil
10. May 2009 06:42
Lately, I have written a lot of multithreaded code in C#. I use the ThreadPool class object to launch and manage many parallel threads - mostly for TCP communications with client applications. It automatically throttles the numbers of active threads by the number of processors. Unfortunately, the ThreadPool class was written before .NET 2.0 and therefore it does not take advantage of generics. So you end up casting function methods and callback parameters. It can be a bit messy.
However, you can simplify things with the following helper class:
1: static class ThreadPoolHelper
2: {
3: public delegate void Function();
4:
5: public static void Execute(Function function)
6: {
7: ThreadPool.QueueUserWorkItem(new WaitCallback(Call), (object)function);
8: }
9:
10: private static void Call(object o)
11: {
12: ((Function)o)();
13: }
14: }
To create a thread in the pool with this helper class, you simple use:
1: TheadPoolHelper.Execute(someFunction);
Where someFunction is the name of a function method.
If you need to pass a parameter, here's the helper class for that too:
1: static class ThreadPoolHelperWithParam<T>
2: {
3: public delegate void Function(T param);
4:
5: public static void Execute(Function function, T param)
6: {
7: ThreadPool.QueueUserWorkItem(new WaitCallback(Call), new KeyValuePair<object, T>((object)function, param));
8: }
9:
10: private static void Call(object o)
11: {
12: KeyValuePair<object, T> lObject = (KeyValuePair<object, T>)o;
13:
14: ((Function)lObject.Key)(lObject.Value);
15: }
16: }
Now you can also pass an object of any type, like this:
1: ThreadPoolHelperWithParam<someObjectType>.Execute(someMethod, someObject);
Where the someObjectType is the type of object you are passing, and someObject with actual object you wish to pass as a parameter. Simple!
250f5685-ef76-471f-86f9-192eea36e391|1|5.0
Tags: c#
Code
by Phil
9. May 2009 20:42
The first challenge to incorporating the Mono Class Libraries into MOSA is how to replace the external method calls in the class libraries with our own custom implementation. There are two basic approaches to this challenge. In part one of this blog series, we will explore the one used by other managed open source projects and its unique challenges.
The most common approach is to replace the call to the external methods with a call to the another custom method instead. This approach seems to be the simplest and most elegant solution – as you only have to supply the CIL code for the custom method and then have the compiler call the replacement method.
Ideally the replacement method would be implemented similar to this:
1: namespace InternalSystem
2: {
3: [TargetNamespace("System")]
4: public class SomeMonoClass
5: {
6: public int NewMethod()
7: {
8: return this.X * this.Y;
9: }
10: }
11: }
Of course, this method will not compile because the member variables X and Y do not exist to the C# compiler. One possible solution is to create stubs for these member variables so they will exist while the code is compiled to CIL. Here we add those two member variables:
1: namespace InternalSystem
2: {
3: [TargetNamespace("System")]
4: public class SomeMonoClass
5: {
6: int X;
7: int Y;
8:
9: public int NewMethod()
10: {
11: return this.X * this.Y;
12: }
13: }
14: }
Now the code compiles. And given some special CIL to native compiler, the external method call will be redirected to this other method instead. Creating stubs to expose these “hidden” member methods and variables seems like a fair compromise. But look at this example:
1: namespace InternalSystem
2: {
3: [TargetNamespace("System")]
4: public class SomeMonoClass
5: {
6: int x;
7: int y;
8:
9: public ClassC NewMethod(ClassA b, ClassB b)
10: {
11: return new ClassC(z, b.X, c.Y);
12: }
13: }
14: }
Now additional stubs are required to represent the ClassA, ClassB, and ClassC classes, and stubs for each of their member methods and variables before this code will compile. Do you see where this is going? Given a rich framework with many dependencies between classes, like the .NET framework, this approach can results in the creation hundreds of stubs!
MOSA will approach this problem in another way, which I will be blogging about next.
by Phil
20. February 2008 05:24
This is an updated to the "NGif, animated GIF Encoder for .NET" article on the The Code Project web site. NGif is a set of C# classes which can create animated GIF images. Microsoft's native GDI library does not support the creation of animated GIFs.
My update supports returning the animated GIF as a MemoryStream object instead of a file. This is helpful on webservers where saving temporary files are not allowed.
Download: NGif_src2.zip (361.62 kb)
Update: If you are looking for more information on animated GIFs using C#, check out HOWTO: create an animated GIF using .Net (C#) by Rick van den Bosch.
e3e99f17-10b8-45d0-aa1e-520907e91c48|0|.0
Tags: gif, c#
Code
by Phil
26. December 2007 22:32
The Photo Gallery addition for BlogEngine.NET is moving forward. We are in the final stages of wrapping up the first release and hope to release it in early January 2008. Here is our list of remaining items:
1. Move all photo settings to the Photo Gallery Control Panel.
2. Write web interface for the Photo Effect extensions.
3. Add option to delete a photo album.
4. Document the use of Cascading Style Sheets (CSS).
5. Add photo gallery web pages to the themes that ship with BlogEngine.NET.
6. Create new theme to highlight the features of the Photo Gallery.
7. Invalid the photo cache when Photo Effects are added or changed.
8. And finally, find and fix any remaining bugs.
If you wish to help out, download the latest source code from CodePlex and try it out. The more developers and testers that participate, the better the release will be.
by Phil
24. December 2007 06:58
I wrote a small SnapShots extension for BlogEngine.NET 1.3.
To install it, download and copy the SnapShots.cs file to the App_Code\Extensions directory.
To set your SnapShots Key, go into the Extension section of the Control Panel and click the edit hyperlink for the SnapShots extension. Enter SnapShot Key on the next page.
You can download the extension from the link below.
Download: SnapShots.cs (2.00 kb) Updated 12/25/07
Update: There are two bugs in the BlogEngine 1.3 release related to Scalar Values in Extensions. I have submitted the patches to the BlogEngine.NET team. In the mean time, you can download the fixed files below:
Download: ExtensionParameter.cs (2.97 kb)
Download: Settings.ascx.cs (10.76 kb)
by Phil
23. December 2007 15:33
This is an upgrade to the Odiogo Extension by Mads Kistensen that uses the new ExtensionManager in the BlogEngine.NET 1.3 release. You can download it by clicking the link below.
Odiogo is a service that reads your RSS feed and creates an mp3 file for each of your blogs. This extension adds the Odigo's Listen now icon to the top of your blog posts.
For more information see Mad's Make your blog talk post.
Download: Odiogo.cs (2.89 kb) Updated 12/25/07
Update: There are two bugs in the BlogEngine 1.3 release related to Scalar Values in Extensions. I have submitted the patches to the BlogEngine.NET team. In the mean time, you can download the fixed files below:
Download: ExtensionParameter.cs (2.97 kb)
Download: Settings.ascx.cs (10.76 kb)