|
Hello,
I'm having a serious problem and I'm stuck with for three days now. I'm currently developping an add-in for Outlook 2007, and I'm having a toolbar and a menu bar.
The problem is, and I really don't understand why, _CommandBarButtonEvents_ClickEventHandler fires events twice, and sometimes even four times !!
Here is my function where I create the CommandButton elements which will be inserted in menu and tool bars :
public void creationBouton_SubMenu(string labelBouton, string nomRessource, Stream imgageStream, short fromToolBarOrManuBar, ref Office.CommandBarButton bouton)
{
Assembly ThisAssembly = Assembly.GetExecutingAssembly();
bouton = null;
if (fromToolBarOrManuBar == fromToolBar)
{
bouton = (Office.CommandBarButton)newToolBar.Controls.Add(MsoControlType.msoControlButton, missing, missing, missing, false);
bouton.Style = Office.MsoButtonStyle.msoButtonIconAndCaptionBelow;
}
else if (fromToolBarOrManuBar == fromMenuBar)
{
bouton = (Office.CommandBarButton)_objNewMenuBar.Controls.Add(MsoControlType.msoControlButton, missing, missing, 1, true);
bouton.Style = Office.MsoButtonStyle.msoButtonIconAndCaption;
}
bouton.Caption = labelBouton;
Random random = new Random(10000);
bouton.Tag = "Basic Tag" + random.Next(1000).ToString();
imgageStream = ThisAssembly.GetManifestResourceStream(namespaceCourant + ".Resources." + nomRessource);
bouton.Picture = MyHost.GettIPictureDispFromPicture(Image.FromStream(imgageStream));
bouton.Click += new Office._CommandBarButtonEvents_ClickEventHandler(Lancement_Formualire_Event);
bouton.Visible = true;
}
And here where I call this method :
private void AddMenubar()
{
Stream imgageStream = null;
try
{
_objMenuBar = this.Application.ActiveExplorer().CommandBars.ActiveMenuBar;
_objNewMenuBar = (Office.CommandBarPopup)_objMenuBar.Controls.Add(Office.MsoControlType.msoControlPopup, missing, missing, missing, false);
if (_objNewMenuBar != null)
{
_objNewMenuBar.Caption = "RPVApp";
_objNewMenuBar.Tag = "RPVApp tag";
creationBouton_SubMenu("Nouveau message civil", "message.png", imgageStream, fromMenuBar, ref bt_NouveauMessageCivil);
creationBouton_SubMenu("Réception messages", "message2.png", imgageStream, fromMenuBar, ref bt_ReceptionMessage);
}
}
And finally here the call to create the tool bar items :
Stream imgageStream = null;
if (newToolBar == null)
{
Office.CommandBars cmdBars = this.Application.ActiveExplorer().CommandBars;
newToolBar = cmdBars.Add("RPVApp_Toolbar", Office.MsoBarPosition.msoBarTop, false, true);
}
try
{
creationBouton_SubMenu("Nouveau message civil", "message.png", imgageStream, 1, ref bt_NouveauMessageCivil);
creationBouton_SubMenu("Réception messages", "message2.png", imgageStream, 1, ref bt_ReceptionMessage);
newToolBar.Visible = true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Thank you in advance for your help !
modified 31-Jul-12 6:25am.
|
|
|
|
|
Effectively you are trying to add the same buttons twice. I know that you are adding them to different locations, but you have added it twice (which means you have ended up with 2 Click event handlers for each button). You only need to assign the Click event handler once. This should work:
if (bouton.Click == null) bouton.Click += new Office._CommandBarButtonEvents_ClickEventHandler(Lancement_Formualire_Event); I've just typed this in the CP editor, so you may need to adjust it.
|
|
|
|
|
Thanks for the quick answer !
It makes sense, but the compiler refuses the clause
if (bouton.Click == null) , saying that this kind of instrction should be placed before += or -= !!
|
|
|
|
|
I wondered about that - you should probably move this creation to just after you have instantiated the button then.
|
|
|
|
|
I tried that but no, still the same problem !
|
|
|
|
|
Never mind - I saw that you were nulling the button field, so this is not it. Try writing out what the sender was in your event handler. You should be able to do it like this:
Button button = sender as Button;
if (sender != null)
{
Debug.WriteLine(button.Tag);
}
|
|
|
|
|
Problem solved. It was the tag !! Random function was giving me the same value each time ! Thank you for your help anyway !
|
|
|
|
|
No problem. If you explicitly seed a random number to a fixed value, whenever you use the Random method on a newly instantiated random generator you get the same values. This line is the offending line:
Random random = new Random(10000); Just use Guid.NewGuid(); to create your tag.
|
|
|
|
|
Hi
I’ve extremely log file that I need to parse, 700M
I need to read the file content and parse each line,
The problem is that I get exception System.outofmemory
In order to solved the memory issue, I think of reading the file in pages
I think of defile pageSize to be 100,000 lines
In order clean memory of array such as fileLinesContent, I think of defining it as null or to call Array.Clean(fileLinesContent)
Is it correct approach to clean memory of array?
string []fileLinesContent;
internal void ReadFile(int pageSize)
{
//To clean memory for garbage collector
fileLinesContent=null;
List<string> fileLines = new List<string>();
int linesNumRead=0;
string line;
while (linesNumRead < pageSize && !srLog.EndOfStream )
{
line = srLog.ReadLine();
linesNumRead ++;
}
fileLinesContent = fileLines.ToArray();
}
}
|
|
|
|
|
Ronenb wrote: Is it correct approach to clean memory of array?
Once the array is out of scope, the garbage-cleaner will reclaim that memory. Might not do it immediate, but when it thinks that it's required.
What are you going to do with the array of lines? Maybe there's a better solution, like passing a stream.
Bastard Programmer from Hell
if you can't read my code, try converting it here[^]
|
|
|
|
|
hi
the array (string []fileLinesContent) is a member of the class, not local member in func,
so my question is how to clean it in order free memory and read next lines in files
i'm reading the lines because i need to know when the line end and parse the element in each line
ronen
|
|
|
|
|
Ronenb wrote: the array (string []fileLinesContent) is a member of the class, not local member in func,
Then it's memory will be released once the object goes out of scope.
Ronenb wrote: so my question is how to clean it in order free memory and read next lines in files
You can't dispose memory manually; there's a garbage-collector to do so. Very long strings are moved to the Large Object Heap, and simply stay there.
Ronenb wrote: i'm reading the lines because i need to know when the line end and parse the element in each line
I'd recommend reading from a Stream , until you encounter that newline-character, and process it immediately. There's little need to keep all that information in memory.
Bastard Programmer from Hell
if you can't read my code, try converting it here[^]
|
|
|
|
|
Thank u all for the replay
i think it is better to use the stream option as you suggested
can you send me example how to stream a file for each line?
should i use StreamFile, StreamRead or MemoryStream service?
thanks
ronen
|
|
|
|
|
Ronenb wrote: should i use StreamFile, StreamRead or MemoryStream service?
A FileStream[^] would be the most appropriate. Next, you use a StreamReader , which has a <a href="http://msdn.microsoft.com/en-us/library/system.io.streamreader.readline.aspx">ReadLine</a>[<a href="http://msdn.microsoft.com/en-us/library/system.io.streamreader.readline.aspx" target="_blank" title="New Window">^</a>] method.
Ronenb wrote: can you send me example how to stream a file for each line?
See the links in this post, I don't provide copy/paste answers.
Bastard Programmer from Hell
if you can't read my code, try converting it here[^]
|
|
|
|
|
Are you sure you don't deliberately sometimes supply copy/paste answers that are for the wrong question?
|
|
|
|
|
Failed to parse your question; can you slice it into simpler pieces for me?
To try and answer that; yes, I do sometimes post code that can be copied/pasted. Yes, I also supply the wrong answer sometimes.
Did I miss anything?
Bastard Programmer from Hell
if you can't read my code, try converting it here[^]
|
|
|
|
|
Eddy Vluggen wrote: Did I miss anything?
Yes.
I had suggested that depending on how stroppy the OP had been, you could deliberately supply the wrong piece of code. Not that I'm advocating this of course. Oh no. Definitely not. Noway. Nosirree.
|
|
|
|
|
|
|
this is a console app that may do what you are after, replace the console.writeline with a call to your parse method
class Program
{
static void Main(string[] args)
{
string filePath = @"D:\ReadMe.txt";
using (var streamReader = new System.IO.StreamReader(filePath))
{
while (!streamReader.EndOfStream)
{
var toParse = streamReader.ReadLine();
System.Console.WriteLine(toParse);
}
}
System.Console.ReadLine();
}
}
|
|
|
|
|
ok
that this is Basically what i did
srLog is type of StreamReader
so my problem was that i didint need to read all file content to memory and then process it
I was thinking it is more efficient to read all file content (with one stroke) and work on it then to access file system for each line(ReadLine) and process it
Isn’t more expensive?
while (!srLog.EndOfStream)
{
line = srLog.ReadLine();
fileLines.Add(line);
}
fileLinesContent = fileLines.ToArray();
|
|
|
|
|
Being honest i don't know which way would perform better, your origional post involved calling ReadLine many times in a loop any way and you were getting memory issues. This way should not be less efficient than the origional proposed solution.
I'd suggest you try it with something many times larger than your expected log file size, if the performance is good then don't stress too much about how you could make it better. If the file IO part of this App is not the bottle neck in the process then don't lose too much time optimising it.
|
|
|
|
|
No, it's not. The way you were reading the file (line by line) and storing it in memory is no less expensive than processing that giant log one line at a time.
You're trying to read 700MB of data into memory and running into OutOfMemory problems. How efficient do you think that is?? By reading everything into memory all at once your solution only works on limited log sizes, dependant on system memory.
If you process every line, one at a time, without reading the entire file into memory, you can process log files of ANY size, up to the file size limit of the operating system and do it without requiring the machine to have terabytes of memory.
|
|
|
|
|
Got it
thanks all
Ronen
|
|
|
|
|
700MB is not that large, you shouldn't run out of memory if you process it efficiently, even if you store the whole thing in memory. Calling List.ToArray is going to double the memory usage, though; you should either store it as a List all the time, or read it into an array to begin with (almost certainly the former).
However, I suspect you are doing some streaming task and you don't actually need the whole thing. Parse each line as it comes, and don't store it; instead store whatever information about a line you need to know, if anything.
|
|
|
|