|
private Image gifImage;
private FrameDimension dimension;
private int frameCount;
private int currentFrame = -1;
private bool reverse;
private int step = 1;
public GifImage(string path)
{
gifImage = Image.FromFile(path);
dimension = new FrameDimension(gifImage.FrameDimensionsList[0]);
frameCount = gifImage.GetFrameCount(dimension);
}
public bool ReverseAtEnd
{
get { return reverse; }
set { reverse = value; }
}
public Image GetNextFrame()
{
currentFrame += step;
if (currentFrame >= frameCount || currentFrame < 1)
{
if (reverse)
{
step *= -1;
currentFrame += step;
}
else
currentFrame = 0;
}
return GetFrame(currentFrame);
}
public Image GetFrame(int index)
{
gifImage.SelectActiveFrame(dimension, index);
return (Image)gifImage.Clone();
}
i saw this coding on the web, i am still confuse on how to use it, can anyone help me with the explaination and example on how i can use it, i am trying to get a certain gif to play and play only once without loop inside a picturebox
using expression blend 4 and VS2010 c#
|
|
|
|
|
i have a requirement that i click on button and download xsl file to client machine and after calling this function i want to redirect user to next page. but after download dialog appears an issue is thrown and control does not return so that i can redirect the page. is there any way of doing that.
|
|
|
|
|
Hi,
I am using LINQ to SQL in my Data Access Layer. I learned that I should not expose IQueryable, rather I should convert the result of IQueryable object to IEnumerable by calling ToList() method. Would you please tell me If IQueryable is better for memory / performance or what are the factors should be related to this decision ?
|
|
|
|
|
What interfaces a class implements have no effect on how the class stores and accesses its data.
Nadia Monalisa wrote: by calling ToList()
That wouldn't make sense if the data doesn't look like a list.
I tend not to make design decisions based simply on "what others say".
|
|
|
|
|
Hi,
Thanks a lot for your reply.
Actually, I am re-factoring my Web Application for better maintainability and memory performance. I host my web application in a shared hosting where I am allowed to use a very limited amount of RAM.
In my Web Application, I used LINQ to SQL where my Code Behind files are directly calling the DataContext class generated by LINQ to SQL Classes. I want to encapsulate the call of DataContext in a Business Logic Layer. I am very much tempted to return IEnumerable Objects from my Business Logic Layer to the Presentation Layer instead of IQueryable objects as I know, IQueryable object means, differed SQL query execution. Moreover, when using IQueryable object, I cannot use most of the LINQ features that are available for LINQ to Object. Because, LINQ to SQL does not have similar translation for many C# methods.
Now, My question, Is it more memory efficient to work with IQueryable object instead of IEnumerable object ? So far I can guess, using IQueryable means, my RAM will be free from loading the whole database table. But If I convert the IQueryable to IEnumerable by calling ToList() or ToArray(), then, the whole object will be loaded into the RAM and reduce performance. Is my guess right ? Would you please give me a better direction for this scenario ?
|
|
|
|
|
Nadia Monalisa wrote: Is it more memory efficient to work with IQueryable object instead of IEnumerable object ?
That depends on how the class is written, not on the interfaces, a class can even implement both interfaces. Or you can define your own interface that expresses exctly what you want.
|
|
|
|
|
It is important to understand the difference between the two: IQueryable pushes the query logic into RDBMS, while IEnumerable does things in the main memory. Although IQueryable cannot perform certain things that IEnumerable can because of the need to translate query logic to SQL, you should try really hard to push as much logic as you can onto the IQueryable side. The reason for it is the data transfer and memory costs: once you call ToList/ToArray, the data described by the query to the left of it gets copied into main memory.
Your own interfaces should rarely expose IQueryable for two major reasons - one is the deferred execution, and the other is query translation. If your class returns IQueryable, the RDBMS will be called at the time the caller decides to go through the results for the first time, which may happen significantly later than your code returns. If callers tend to not enumerate the results at all in a significant number of cases, calling AsEnumerable instead of ToLost/ToArray may save you some unnecessary roundtrips to RDBMS; if callers go through your query results immediately, you are better off calling ToList/ToArray yourself. The other reason to not expose IQueryable in your data layer is to avoid errors when your callers apply LINQ methods to your results: these LINQ queries will be translated to RDBMS, potentially resulting in run-time errors.
As a side note, if this is a new project, using Entity Framework instead of LINQ to SQL is highly advisable: at this point, LINQ to SQL technology receives only bug fixes from Microsoft; the new development is concentrated in EF. The good news is that much of what you learned about querying in LINQ to SQL applies in EF as well.
|
|
|
|
|
dasblinkenlight wrote: IQueryable pushes the query logic into RDBMS, while IEnumerable does things in the main memory
That may be how Microsoft implemented their classes, but the poster need not do it that way. There is nothing about an interface that specifies how it must be implemented. When you refer to an interface you neither know nor care what goes on in the background.
|
|
|
|
|
Actually, on a very high level, that is how everyone is expected to implement IQueryable. In addition to being a shell that shields users from the details of implementation, each interface has a clear purpose in the overall design. According to documentation[^], the purpose of IQueryable is to "provide functionality to evaluate queries against a specific data source". In case of LINQ to SQL, this means pushing the query logic into RDBMS. Doing it in any other way would be a deviation from the stated purpose of the interface.
|
|
|
|
|
So what? The compiler can't enforce intents expressed in documentation. All that matters is that the class provides the signatures required by the interface -- the members don't even need to do anything, or they can throw NotImplementedExceptions for all the compiler cares.
A developer can implement an interface any darn way he likes; an IEnumerable can access a database or a Random or any old thing, an IQueryable can access a Web Service or IME or shared memory, the interfaces don't care. It all depends on what the developer needs to do. It is then up to the user of the class to decide whether or not that class provides the desired information in a useful manner. Other than that, the class is a black box and you shouldn't go poking your fingers in it.
|
|
|
|
|
There are two sides to interfaces: one for communicating with a compiler, and one for communicating with programmers who read your code. You keep arguing that there's only the first side, pretending the second side does not exist. However, it's there, and I am sure you've been made painfully aware of it on more than one occasion, when the code compiled but did not work. There are legitimate concerns that compilers simply cannot enforce, yet these concerns do not become less relevant because of it. For example, compilers cannot enforce exact type casts inside fast enumeration loops, but this means only that the programmers should pay more attention. There is more to implementing an interface than providing implementations to all its methods so that the compiler stops complaining. For example, if you implement IQueryable in a way that reads everything from the database and then filters in memory, you will "provide the desired information", but not "in a useful manner". That does not make your class useless - others may still use it in their code. It's just that they will not be using it in a way they normally use an IQueryable. I completely agree with your "class is a black box" comment, yet "poking one's finger into a class" is drastically different from understanding the intent behind its implementation.
|
|
|
|
|
dasblinkenlight wrote: one for communicating with programmers who read your code
Which is the name of the interface and the signatures of the members -- any intent expressed in other documentation, while instructive, is not part of the contract and may be incorrect or may not have been obeyed by the developer of any particular class that implements the interface. Such documentation should be taken with a shot of tequila.
My own pet peeve with this regard is the documentation of IDataReader, which Microsoft's providers implement in surprising ways.
|
|
|
|
|
Name+signatures is a good start, but there are other items there that everyone follows: - Documentation may ask not to pass null or negative values for certain arguments, - Documentation may ask to pass only sorted collections to certain methods (e.g. a binary search), - Documentation may ask not to call a method in a particular state (e.g. creating a statement on a closed connection), - Documentation may ask to call a method in a context of an ambient transaction, - Documentation may ask not to call a method before calling another method (e.g. obtaining a write lock without releasing a read lock first) The list goes on and on. I'm sure there are classes and methods with awful documentation, as well as implementations written without regard to the interface documentation (as you mentioned). But that does not mean that all documentation is somehow bad, only that there is some room to grow
|
|
|
|
|
That sounds like implementation-specific documentation, not interface documentation. One needs to keep the two concepts separate.
|
|
|
|
|
dasblinkenlight wrote: In case of LINQ to SQL, this means pushing the query logic into RDBMS
Which has no bearing on any other particular implementation the OP may be considering.
|
|
|
|
|
I'm using VS 2010 on Windows 7. I found this code in a Google search, and it compiles and runs, but when I pass in values to SetVolume, there is no change in the sound volume:
public static class Volume
{
[DllImport("winmm.dll")]
private static extern int waveOutGetVolume(IntPtr hwo, out uint dwVolume);
[DllImport("winmm.dll")]
private static extern int waveOutSetVolume(IntPtr hwo, uint dwVolume);
public static int GetVolume()
{
uint CurrVol = 0;
waveOutGetVolume(IntPtr.Zero, out CurrVol);
ushort CalcVol = (ushort)(CurrVol & 0x0000ffff);
int volume = CalcVol / (ushort.MaxValue / 10);
return volume;
}
public static void SetVolume(int Volume)
{
int NewVolume = ((ushort.MaxValue / 10) * Volume);
uint NewVolumeAllChannels = (((uint)NewVolume & 0x0000ffff) | ((uint)NewVolume << 16));
waveOutSetVolume(IntPtr.Zero, NewVolumeAllChannels);
}
}
I found a couple of Mixer type projects here on CP, but they're over the top as far as wat I'm looking for. I simply want to change the volume level of the speakers.
Anyone know how to do this?
>
Everything makes sense in someone's mind
|
|
|
|
|
I've never used the Wave functions but I have extensively used the MIDI functions that are very similar and in the same dll.
I belive you may need to call WaveOutOpen first to get a valid handle, then call SetVolume using that handle and finally call WaveOutClose , again using that handle.
I haven't looked at the documentation at all so I may be way off base here, but this is the way the stuff I have used works.
|
|
|
|
|
Could you share some code? I cannot for the life of me find any C# code that handles getting and setting the speaker volume.
Everything makes sense in someone's mind
|
|
|
|
|
I've had a play and this seems to work. This is the extent of my testing but I hope it helps!
It's quite a lot of code - welcome to the world of PInvoke. There is more that needs doing such as checking the result of each API call and raising a custom exception if != MMSYSERR_NOERROR etc...
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
internal struct WAVEFORMATEX
{
public short wFormatTag;
public short nChannels;
public int nSamplesPerSec;
public int nAvgBytesPerSec;
public short nBlockAlign;
public short wBitsPerSample;
public short cbSize;
}
using System;
using System.Runtime.InteropServices;
internal delegate void waveOutProc(
IntPtr hwo,
int uMsg,
IntPtr dwInstance,
IntPtr dwParam1,
IntPtr dwParam2);
internal static class NativeMethods
{
public const int MMSYSERR_NOERROR = 0;
public const int CALLBACK_FUNCTION = 0x00030000;
[DllImport("winmm.dll", SetLastError = true)]
public static extern int waveOutOpen(
out IntPtr phwo,
int uDeviceID,
ref WAVEFORMATEX pwfx,
waveOutProc dwCallback,
IntPtr dwCallbackInstance,
int fdwOpen);
[DllImport("winmm.dll", SetLastError = true)]
public static extern int waveOutClose(IntPtr hwo);
[DllImport("winmm.dll", SetLastError = true)]
public static extern int waveOutGetVolume(
IntPtr hwo,
out uint pdwVolume);
[DllImport("winmm.dll", SetLastError = true)]
public static extern int waveOutSetVolume(
IntPtr hwo,
uint dwVolume);
}
using System;
public class WaveOut : IDisposable
{
private waveOutProc callback;
private IntPtr handle;
private int id;
public WaveOut(int id)
{
callback = new waveOutProc(Callback);
this.id = id;
}
~WaveOut()
{
Dispose(false);
}
public int ID
{
get { return id; }
}
private void Callback(IntPtr hwo, int uMsg, IntPtr dwInstance,
IntPtr dwParam1, IntPtr dwParam2)
{
}
public void Close()
{
if (handle != IntPtr.Zero)
NativeMethods.waveOutClose(handle);
handle = IntPtr.Zero;
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
}
if (handle != IntPtr.Zero)
Close();
}
public uint GetVolume()
{
uint volume = uint.MaxValue;
if (handle != IntPtr.Zero)
NativeMethods.waveOutGetVolume(handle, out volume);
return volume;
}
public void Open()
{
if (handle == IntPtr.Zero)
{
WAVEFORMATEX waveFormatEx = new WAVEFORMATEX();
waveFormatEx.wFormatTag = 1;
waveFormatEx.nChannels = 2;
waveFormatEx.nSamplesPerSec = 44100;
waveFormatEx.wBitsPerSample = 16;
waveFormatEx.nBlockAlign = (short)(waveFormatEx.nChannels * (waveFormatEx.wBitsPerSample / 8));
waveFormatEx.nAvgBytesPerSec = waveFormatEx.nSamplesPerSec * waveFormatEx.nBlockAlign;
NativeMethods.waveOutOpen(out handle, id,
ref waveFormatEx, callback, IntPtr.Zero,
NativeMethods.CALLBACK_FUNCTION);
}
}
public void SetVolume(uint volume)
{
if (handle != IntPtr.Zero)
NativeMethods.waveOutSetVolume(handle, volume);
}
}
using System;
internal class Test
{
private static void ConvertFromVolume(uint volume, out int left, out int right)
{
left = (int)volume & 0xFFFF;
right = (int)(volume >> 16) & 0xFFFF;
}
private static uint ConvertToVolume(int left, int right)
{
return (uint)right << 16 | (ushort)left;
}
public void Run()
{
WaveOut waveOut = new WaveOut(0);
waveOut.Open();
int originalLeft;
int originalRight;
ConvertFromVolume(waveOut.GetVolume(), out originalLeft, out originalRight);
Console.WriteLine(
"Left: {0}, Right: {1}",
originalLeft, originalRight);
int newLeft = 32768;
int newRight = 32768;
waveOut.SetVolume(ConvertToVolume(newLeft, newRight));
ConvertFromVolume(waveOut.GetVolume(), out newLeft, out newLeft);
Console.WriteLine(
"Left: {0}, Right: {1}",
newLeft, newLeft);
waveOut.SetVolume(ConvertToVolume(originalLeft, originalRight));
ConvertFromVolume(waveOut.GetVolume(), out newLeft, out newLeft);
Console.WriteLine(
"Left: {0}, Right: {1}",
newLeft, newLeft);
waveOut.Close();
}
}
using System;
class Program
{
static void Main(string[] args)
{
new Test().Run();
Console.ReadKey();
}
}
|
|
|
|
|
Thanks, I'll have a go at it.
Everything makes sense in someone's mind
|
|
|
|
|
Ok, I've coded it.
What should be happening when I run this?
Everything makes sense in someone's mind
|
|
|
|
|
When I run it on my system it
1. retrieves the original volume
2. then changes it and retrieves it agin to show it is changed.
3. It then sets it back to the original and retrieves it again to it has been changed back.
If you remove step 3 it should remain changed to whatever you set it to in 2. Check out the code in Test.Run() , I have commented it all.
|
|
|
|
|
Ok, that's what I figred should be happening.
I'm listening to music right now via headphones. When I run this, the sound level doesn't change.
Everything makes sense in someone's mind
|
|
|
|
|
I haven't actually tested it with audio - just the values from GetVolume so I see that the driver has responded. There could be one of two things here...
1. The device ID needs to be the correct one for the device who's volume you want to adjust - I'm not sure without further research how to determine the correct ID for the main audio out device/master
2. Maybe the API only adjusts the volume for the audio stream you play directly - unlikely though.
Edit: you can use waveOutGetNumDevs to get the number of devices and waveOutGetDevCaps in conjuction with WAVEOUTCAPS to get the correct device. Check out this[^] page. If you can't resolve this, let me know and I'll have another look tomorrow, bedtime for me here in the UK - good luck!
|
|
|
|
|
Are you using Vista or Windows 7? If so, this[^] may explain why it's not working and a possible workaround?
Edit: Tested demo app and it works!
|
|
|
|
|