在windows切换线程之前强制完成对c#方法的异步调用
我有一个项目,它使用Parallel.For调用立即执行文件的批量修改,因为它们都需要相当长的时间,我希望在修改过程中提供反馈。整个过程还将备份更改的文件,并在执行过程中创建一个撤消批处理命令。撤消文件必须输出撤消步骤并刷新撤消文件缓冲区,然后再执行任何其他任务,以便在更改文件的过程实际开始之前保存所有批处理步骤(复制原始文件和删除副本)。例如如果我要更改两个文件“A.bin”“B.bin”,我希望批处理文件显示:在windows切换线程之前强制完成对c#方法的异步调用,c#,multithreading,streamwriter,parallel.for,C#,Multithreading,Streamwriter,Parallel.for,我有一个项目,它使用Parallel.For调用立即执行文件的批量修改,因为它们都需要相当长的时间,我希望在修改过程中提供反馈。整个过程还将备份更改的文件,并在执行过程中创建一个撤消批处理命令。撤消文件必须输出撤消步骤并刷新撤消文件缓冲区,然后再执行任何其他任务,以便在更改文件的过程实际开始之前保存所有批处理步骤(复制原始文件和删除副本)。例如如果我要更改两个文件“A.bin”“B.bin”,我希望批处理文件显示: copy "A.original" "A.bin&
copy "A.original" "A.bin"
delete "A.original"
copy "B.original" "B.bin"
delete "B.original"
问题在于,异步调用可以在对生成上述输出的方法的并行调用之间切换,该输出创建具有以下输出的文件:
copy "A.original" "A.bin"
copy "B.original" "B.bin"
delete "A.original"
delete "B.original"
这会造成这样一种情况,即如果程序崩溃或在每个步骤中文件之间的过程中出现错误,“撤消”脚本最终会留下“删除”行,从而使撤消批处理留下需要删除的垃圾文件
在windows切换到其他线程之前,是否有方法标记/强制完成方法或块?从我对async/await的理解来看,这是一个不同的用例,无法实现我所需要的(这是我在网上查找如何执行类似操作时可以找到的唯一搜索结果)
下面是将步骤实际添加到批处理文件的代码。整个方法必须在没有线程开关的情况下完全执行:
internal static void AddCommit(CommitType type, string sourcePath, string destPath = null)
{
if ((type & CommitType.RestoreBackup) != 0)
{
if (destPath == null)
throw new ArgumentNullException();
UndoScript.WriteLine("copy \"" + sourcePath + "\" \"" + destPath + "\" /y");
}
if ((type & CommitType.UndoDeleteBackup) != 0)
UndoScript.WriteLine("delete \"" + sourcePath + "\" /q");
if ((type & CommitType.CommitDeleteBackup) != 0)
CommitScript.WriteLine("delete \"" + sourcePath + "\" /q");
UndoScript.Flush();
if (CommitScript != null)
CommitScript.Flush();
}
你的问题中有很多东西,很难准确把握你对答案的期望。也就是说,实际上只有一个明确的问题: 在windows切换到其他线程之前,是否有方法标记/强制完成方法或块 这很容易回答:不 像Windows这样的先发制人多任务操作系统的全部前提是,进程基本上无法控制线程的上下文切换 最接近的方法是调整线程优先级。在某些情况下,这可能类似于控制上下文切换,但即使这样也不能完全控制流程,原因如下:
因此,最好的解决方案可能是完全放弃整个并发方面。您应该向自己证明,多线程解决方案的测量性能实际上比单线程解决方案快得多,足以证明额外的复杂性。在AddCommit中首先将所有命令写入字符串,然后只执行一个UndoScript,最后执行WriteLine(希望您在UndoScript中使用锁,以便多个线程不能同时写入文件)您熟悉该语句吗?请注意,多线程处理很困难,并提供了许多令人兴奋的新方法来打击您自己!将所有命令写入stringbuilder可以解决眼前的问题。