我有一个在多个线程上创建文件的脚本。偶尔,我会在document.SaveAs()调用上得到以下错误:
{“Word无法保存或创建此文件。请确保您的磁盘 想要保存文件不完整,写保护或损坏。\ r (C:\ ... \ fileName.docx)“}
这很令人发狂,因为它似乎有时发生而不是其他发生。我一直在花费最后一天试图解决这个问题,而且进展甚微。我排除的一件事是有多个线程试图创建同一个文件的可能性。我确信这不会发生。我的代码中是否有任何可能导致此问题的内容,或者在使用com对象时这只是生活中的事实?我正在做的正是那些代码教程所说的,也许我应该放弃使用多个线程?
BuildDocumentsThread(){
var word = new Microsoft.Office.Interop.Word.Application();
word.Options.CreateBackup = false;
var wordQuit = (Microsoft.Office.Interop.Word._Application)word;
foreach(var value in values){
FormBuilder.BuildSummaryForm(word, value);
}
wordQuit.Quit();
}
public static void BuildSummaryForm(Application word, string value) {
var summaryFormPath = Utilities.GetSummaryFilePath(value);
if (File.Exists(summaryFormPath))
File.Delete(summaryFormPath);
object path = summaryFormPath;
object readOnly = false;
object o = System.Reflection.Missing.Value;
var document = word.Documents.Add(ref o, ref o, ref o, ref o);
document.Activate();
Paragraph p1 = document.Content.Paragraphs.Add(ref o);
p1.Range.Font.Name = "Arial";
p1.Range.Font.Size = 10;
p1.Range.Text = value;
document.SaveAs(ref path, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o);
document.Close();
}
答案 0 :(得分:1)
如果评论中John Koerner描述的SaveAs不是线程安全的,您可以尝试锁定SaveAs并关闭。
在这种情况下,我确信多线程过程将再次有用,但这是最糟糕的尝试。至少你会知道你的错误是来自SaveAs函数。
在评论后添加一些信息:
添加一个类变量来创建锁
private static object _savelock = new object();
然后在你的工作人员:
lock(_savelock)
{
document.SaveAs(ref path, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o);
}
document.Close();
在这种情况下,不会同时进行保存操作。也可能需要锁定关闭
在这种情况下,你真的不在乎它是否是相同的单词实例。在这两种情况下它都会起作用。
主要缺点是如果保存操作占用线程的95%的时间,多线程几乎变得无用,因为通过锁定保存操作,只有5%的进程实际上是多线程的。但是,如果“释放”ui并让用户在流程运行期间继续工作是目标,那么这是一个可行的解决方案。
检查http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx是否锁定pricinple