c# - 我有时会在 System.Threading.Tasks.TaskCompletionSource<bool> 上遇到异常,我该如何解决?

标签 c# .net winforms

我有一个从 fomr1 的构造函数调用的观察器方法:

FileSystemWatcher watcher;
        private void WatchDirectory()
        {
            watcher = new FileSystemWatcher();
            watcher.Path = userVideosDirectory;
            watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size;
            watcher.Filter = "*.mp4";
            watcher.Changed += new FileSystemEventHandler(OnChanged);
            watcher.EnableRaisingEvents = true;
        } 

然后是Onchanged事件:

private void OnChanged(object source, FileSystemEventArgs e)
        {

                var info = new FileInfo(e.FullPath);
                fileforupload = info.FullName;
                if (IsFileLocked(info) == false)
                {
                    sy.SetResult(true);
                    watcher.EnableRaisingEvents = false;
                    watcher.Dispose();
                }
        }

这是 IsFileLocked 方法:

protected virtual bool IsFileLocked(FileInfo file)
        {
            FileStream stream = null;
            try
            {
                stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
            }
            catch (IOException)
            {
                return true;
            }
            finally
            {
                if (stream != null)
                    stream.Close();
            }

我在这个方法中使用它:

public string SendResponse(HttpListenerRequest request)
        {            
                    sy = new TaskCompletionSource<bool>();
                    WatchDirectory();
                    sy.Task.Wait();
                    Youtube_Uploader youtubeupload = new Youtube_Uploader(fileforupload);
                    return false;
        }

异常是在行的OnChanged事件中:

sy.SetResult(true);

是:

TaskCompletionSource<bool> sy;

在 OnChanged 方法中我做了:

watcher.EnableRaisingEvents = false;
watcher.Dispose();

但有时仍然会出现异常。 异常(exception)情况是:

An attempt was made to transition a task to a final state when it had already completed

System.InvalidOperationException was unhandled
  _HResult=-2146233079
  _message=An attempt was made to transition a task to a final state when it had already completed.
  HResult=-2146233079
  IsTransient=false
  Message=An attempt was made to transition a task to a final state when it had already completed.
  Source=mscorlib
  StackTrace:
       at System.Threading.Tasks.TaskCompletionSource`1.SetResult(TResult result)
       at Automatic_Record.Form1.OnChanged(Object source, FileSystemEventArgs e) in d:\C-Sharp\Automatic_Record\Automatic_Record\Automatic_Record\Form1.cs:line 197
       at System.IO.FileSystemWatcher.OnChanged(FileSystemEventArgs e)
       at System.IO.FileSystemWatcher.NotifyFileSystemEventArgs(Int32 action, String name)
       at System.IO.FileSystemWatcher.CompletionStatusChanged(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* overlappedPointer)
       at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
  InnerException: 

最佳答案

发生这种情况是因为 FileSystemWatcher 会为任何单个更改触发多个 onChanged 事件。因此,在您禁用 EnableRaisingEvent 之前,观察者可能已经触发了多个 onChanged 事件。您需要在 onChanged 方法中加锁,或者不使用 TaskCompletionSource.SetResult 而使用 TaskCompletionSource.TrySetResult。

有关 TrySetResult 的详细信息,请参阅:https://msdn.microsoft.com/en-us/library/dd449176(v=vs.110).aspx

关于c# - 我有时会在 System.Threading.Tasks.TaskCompletionSource<bool> 上遇到异常,我该如何解决?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31953418/

相关文章:

c# - 鼠标双击仅在右键单击时触发

c# - 将附加 header 发送到 System.Windows.Forms.WebBrowser

c# - 是否有 UltraWinGrid 的替代品?

c# - 如何访问 JArray 的元素(或迭代它们)

c# - 如何启用 C# 9.0-preview

c# - 从使用 UdpClient 接收的 UDP 包中获取客户端 IP

.net - Azure DocumentDB - 源自脚本的请求不能引用除提交客户端请求的分区键之外的分区键

c# - 从 DataTable 创建数据透视表

c# - Microsoft.Practices.EnterpriseLibrary.Data : execute multiple statements in one transaction

c# - 如何在不使用 asp.net 中的绑定(bind)和模板字段的情况下将数据表与 GridView 绑定(bind)?