本文介绍了是什么导致MoveFileTransactedW挂起?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们在从.Net 4 C#应用程序保存文件时使用MoveFileTransactedW(也就是说,我们写入临时文件,然后将文件移动到其中实际位置)。

We are using MoveFileTransactedW when saving files from our .Net 4 C# application (that is, we write to a temporary file and then move the file to its actual location).

在两台独立的计算机(都是Windows 7)上,我们很少发生似乎对MoveFileTransactedW的调用永远不会返回的情况(至少根据我们查看的小型数据库) 。

On two separate computers (both Windows 7) we have had a rare occurrence where it seems the call to MoveFileTransactedW never returns (at least according to the minidumps we looked at).

执行移动的代码看起来像这样(我删除了一些代码来处理不支持事务的情况以及其他一些错误处理):

The code that executes the move, looks like this (i removed some code that handles the case where transactions arent supported as well as some other error handling):

 

   var transaction = CreateTransaction( IntPtr.Zero, IntPtr.Zero, 0, 0, 0, 0, IntPtr.Zero );

   try {
     bool result = MoveFileTransactedW( src, dest, IntPtr.Zero, IntPtr.Zero, MoveFileFlags.MOVEFILE_REPLACE_EXISTING | MoveFileFlags.MOVEFILE_WRITE_THROUGH, transaction );
     result &= CommitTransaction( transaction );
     if ( !result ) {
      File.Replace( src, dest, null );
     }
    }
    finally {
     CloseHandle( transaction );
    }

并且DLL导入:

  [DllImport( "KtmW32.dll" )]
   private static extern bool CommitTransaction( IntPtr transaction );

  [DllImport( "Kernel32.dll" )]
   private static extern bool CloseHandle( IntPtr handle );

  [DllImport( "KtmW32.dll" )]
   private static extern IntPtr CreateTransaction( IntPtr lpEventAttributes, IntPtr UOW, UInt32 createOptions, UInt32 isolationLevel, UInt32 isolationFlags, UInt32 timeOut, IntPtr description );

  [return: MarshalAs( UnmanagedType.Bool )]
   [DllImport( "kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true )]
   private static extern bool MoveFileTransactedW( [In] string lpExistingFileName, [In] string lpNewFileName, [In] IntPtr lpProgressRoutine, [In] IntPtr lpData, [In] MoveFileFlags dwFlags, [In] IntPtr hTransaction );



任何想法可能导致什么?我尝试过各种场景,涉及在同一个文件上打开的其他事务,锁定文件等,但MoveFileTransactedW总是返回。


Any ideas what could cause this? I have tried various scenarios involving other transactions open on the same file, locking the files etc, but MoveFileTransactedW always returns.

stacktrace的最后一部分是:

The last part of the stacktrace is this:

> () 

> ntdll.dll!_KiFastSystemCallRet@0() 

  ()  + 0xc字节

  ntdll.dll!_NtSetInformationFile@20()  + 0xc bytes

  ()  + 0x18c字节

  kernel32.dll!_MoveFileWithProgressTransactedW@24()  + 0x18c bytes

  ()  + 0x47字节

  kernel32.dll!_MoveFileTransactedW@24()  + 0x47 bytes

  [管理到原生过渡]

  [Managed to Native Transition]

也许我应该避免使用MOVEFILE_WRITE_THROUGH标志?根据没有必要,但我发现描述有点不清楚,因此无论如何我添加了它:)

Perhaps i should avoid using the MOVEFILE_WRITE_THROUGH flag? According to http://msdn.microsoft.com/en-us/library/aa365241(v=vs.85).aspx it is not necessary, but i found the description a bit unclear, and therefore i added it anyway :)

推荐答案

我建议两件事:

- 删除MOVEFILE_WRITE_THROUGH标志(不确定这是否是问题)

- Remove the MOVEFILE_WRITE_THROUGH flag (not sure if this is the issue though)

- 调用CreateTransaction时,为第6个参数指定合理的超时,如果事务在程序中止,则实现一些重试逻辑

- When you call CreateTransaction, specify a reasonable timeout for the 6th parameter, and implement some retry logic if the transaction is aborted in your program


这篇关于是什么导致MoveFileTransactedW挂起?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-27 04:49
查看更多