C
Chuck P
I have around a 1000 word files to convert from doc to html.
It's very slow. So I threaded it. When I threaded it frequently pukes, with
various error messages. Also I end up getting lots of copies of WinWord in
taskmanager after the program crashes.
I'm not an expert on Comm interop and I read this:
http://msdn2.microsoft.com/en-us/li...services.marshal.releasecomobject(VS.71).aspx
The runtime callable wrapper has a reference count that is incremented every
time a COM interface pointer is mapped to it. The ReleaseComObject method
decrements the reference count of a runtime callable wrapper.
I wondering if the runtime callable wrapper is counting or trying to re-use
com objects which are disposed.
Is word/com some how doing something on the main thread and causing the pukes.
static object workerLocker = new object();
static int runningWorkers = 0;
private void ConvertFiles()
{
if (!Directory.Exists(txtSourceDirectory.Text))
txtStatus.Text = "Source Directory does not exist.";
else if (!Directory.Exists(txtDestinationDirectory.Text))
txtStatus.Text = "Destination Directory does not exist.";
else
{
Directory.Delete(txtDestinationDirectory.Text, true);
Directory.CreateDirectory(txtDestinationDirectory.Text);
string[] SourceFiles =
Directory.GetFiles(txtSourceDirectory.Text, "*.doc");
foreach (string fileName in SourceFiles)
{
if (!Path.GetFileName(fileName).StartsWith("."))
{
lock (workerLocker)
{
runningWorkers++; Monitor.Pulse(workerLocker);
}
ThreadPool.QueueUserWorkItem(new
WaitCallback(SaveToHTML), fileName);
}
}
lock (workerLocker)
{
while (runningWorkers > 0) Monitor.Wait(workerLocker);
}
GC.Collect();
}
}
private void SaveToHTML(Object sfileName)
{
string fileName = (string)sfileName;
object Missing = System.Reflection.Missing.Value;
object readOnly = true;
object isVisible = false;
object fileToOpen = (object)fileName;
object fileToSave =
(object)Path.Combine(txtDestinationDirectory.Text,
Path.GetFileName(fileName)).Replace(".doc", ".html");
object FileFormat = Word.WdSaveFormat.wdFormatFilteredHTML;
Word._Application word = null;
Word._Document doc = null;
word = new Word.Application();
doc = new Word.Document();
doc = word.Documents.Open(ref fileToOpen,
ref Missing, ref readOnly, ref Missing, ref Missing,
ref Missing, ref Missing, ref Missing, ref Missing,
ref Missing, ref Missing, ref isVisible, ref Missing,
ref Missing, ref Missing, ref Missing);
doc.SaveAs(ref fileToSave,
ref FileFormat, ref Missing, ref Missing, ref Missing,
ref Missing, ref Missing, ref Missing, ref Missing,
ref Missing, ref Missing, ref Missing, ref Missing,
ref Missing, ref Missing, ref Missing);
doc.Close(ref Missing, ref Missing, ref Missing);
NAR(doc);
doc = null;
word.Quit(ref Missing, ref Missing, ref Missing); //closes all
documents
NAR(word);
word = null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
lock (workerLocker)
{
runningWorkers--; Monitor.Pulse(workerLocker);
SetStatus(runningWorkers.ToString() + " " + fileName +
Environment.NewLine);
}
Application.DoEvents();
}
delegate void SetStringDelegate(string parameter);
void SetStatus(string status)
{
if (!InvokeRequired)
{
txtStatus.Text += status;
this.Refresh();
}
else
Invoke(new SetStringDelegate(SetStatus), new object[] {
status });
}
private void NAR(object o)
{//http://support.microsoft.com/default.aspx?scid=kb;EN-US;317109
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(o);
}
catch { }
finally
{
o = null;
}
}
It's very slow. So I threaded it. When I threaded it frequently pukes, with
various error messages. Also I end up getting lots of copies of WinWord in
taskmanager after the program crashes.
I'm not an expert on Comm interop and I read this:
http://msdn2.microsoft.com/en-us/li...services.marshal.releasecomobject(VS.71).aspx
The runtime callable wrapper has a reference count that is incremented every
time a COM interface pointer is mapped to it. The ReleaseComObject method
decrements the reference count of a runtime callable wrapper.
I wondering if the runtime callable wrapper is counting or trying to re-use
com objects which are disposed.
Is word/com some how doing something on the main thread and causing the pukes.
static object workerLocker = new object();
static int runningWorkers = 0;
private void ConvertFiles()
{
if (!Directory.Exists(txtSourceDirectory.Text))
txtStatus.Text = "Source Directory does not exist.";
else if (!Directory.Exists(txtDestinationDirectory.Text))
txtStatus.Text = "Destination Directory does not exist.";
else
{
Directory.Delete(txtDestinationDirectory.Text, true);
Directory.CreateDirectory(txtDestinationDirectory.Text);
string[] SourceFiles =
Directory.GetFiles(txtSourceDirectory.Text, "*.doc");
foreach (string fileName in SourceFiles)
{
if (!Path.GetFileName(fileName).StartsWith("."))
{
lock (workerLocker)
{
runningWorkers++; Monitor.Pulse(workerLocker);
}
ThreadPool.QueueUserWorkItem(new
WaitCallback(SaveToHTML), fileName);
}
}
lock (workerLocker)
{
while (runningWorkers > 0) Monitor.Wait(workerLocker);
}
GC.Collect();
}
}
private void SaveToHTML(Object sfileName)
{
string fileName = (string)sfileName;
object Missing = System.Reflection.Missing.Value;
object readOnly = true;
object isVisible = false;
object fileToOpen = (object)fileName;
object fileToSave =
(object)Path.Combine(txtDestinationDirectory.Text,
Path.GetFileName(fileName)).Replace(".doc", ".html");
object FileFormat = Word.WdSaveFormat.wdFormatFilteredHTML;
Word._Application word = null;
Word._Document doc = null;
word = new Word.Application();
doc = new Word.Document();
doc = word.Documents.Open(ref fileToOpen,
ref Missing, ref readOnly, ref Missing, ref Missing,
ref Missing, ref Missing, ref Missing, ref Missing,
ref Missing, ref Missing, ref isVisible, ref Missing,
ref Missing, ref Missing, ref Missing);
doc.SaveAs(ref fileToSave,
ref FileFormat, ref Missing, ref Missing, ref Missing,
ref Missing, ref Missing, ref Missing, ref Missing,
ref Missing, ref Missing, ref Missing, ref Missing,
ref Missing, ref Missing, ref Missing);
doc.Close(ref Missing, ref Missing, ref Missing);
NAR(doc);
doc = null;
word.Quit(ref Missing, ref Missing, ref Missing); //closes all
documents
NAR(word);
word = null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
lock (workerLocker)
{
runningWorkers--; Monitor.Pulse(workerLocker);
SetStatus(runningWorkers.ToString() + " " + fileName +
Environment.NewLine);
}
Application.DoEvents();
}
delegate void SetStringDelegate(string parameter);
void SetStatus(string status)
{
if (!InvokeRequired)
{
txtStatus.Text += status;
this.Refresh();
}
else
Invoke(new SetStringDelegate(SetStatus), new object[] {
status });
}
private void NAR(object o)
{//http://support.microsoft.com/default.aspx?scid=kb;EN-US;317109
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(o);
}
catch { }
finally
{
o = null;
}
}