我一直有时变得异常的System.Threading.Tasks.TaskCompletionSource<布尔>我该如何解决呢? [英] I keep getting exception sometimes on System.Threading.Tasks.TaskCompletionSource<bool> how can i solve it?

查看:273
本文介绍了我一直有时变得异常的System.Threading.Tasks.TaskCompletionSource<布尔>我该如何解决呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个观察者方法,我正在从fomr1的构造函数调用:

  FileSystemWatcher的守望者;
        私人无效WatchDirectory()
        {
            观察家=新FileSystemWatcher的();
            watcher.Path = userVideosDirectory;
            watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size;
            watcher.Filter =* .MP4;
            watcher.Changed + =新FileSystemEventHandler(调用onChanged);
            watcher.EnableRaisingEvents = TRUE;
        }
 

然后onChanged事件,这:

 私人无效调用onChanged(对象源,FileSystemEventArgs E)
        {

                VAR信息=新的FileInfo(e.FullPath);
                fileforupload = info.FullName;
                如果(IsFileLocked(信息)==假)
                {
                    sy.SetResult(真正的);
                    watcher.EnableRaisingEvents = FALSE;
                    watcher.Dispose();
                }
        }
 

这是IsFileLocked方式:

 受保护的虚拟布尔IsFileLocked(FileInfo的文件)
        {
            的FileStream流= NULL;
            尝试
            {
                流= File.open方法(FileMode.Open,FileAccess.ReadWrite,FileShare.None);
            }
            赶上(IOException异常)
            {
                返回true;
            }
            最后
            {
                如果(流!= NULL)
                    stream.Close();
            }
 

和我使用它在此方法:

 公共字符串SendResponse(HttpListenerRequest要求)
        {
                    SY =新TaskCompletionSource<布尔>();
                    WatchDirectory();
                    sy.Task.Wait();
                    Youtube_Uploader youtubeupload =新Youtube_Uploader(fileforupload);
                    返回false;
        }
 

唯一的例外是在上线的onChanged事件,这:

  sy.SetResult(真正的);
 

SY是:

  TaskCompletionSource<布尔> SY;
 

在OnChanged方法我所做的:

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

但仍然得到有时例外。 唯一的例外是:

 试图转型任务到最终状态时,它已经完成

System.InvalidOperationException了未处理
  _HResult = -2146233079
  _Message =试图转型任务到最终状态时,它已经完成。
  HResult的= -2146233079
  IsTransient = FALSE
  消息=试图转型任务到最终状态时,它已经完成。
  来源= mscorlib程序
  堆栈跟踪:
       在System.Threading.Tasks.TaskCompletionSource`1.SetResult(TResult结果)
       在Automatic_Record.Form1.OnChanged(对象源,FileSystemEventArgs E)在d:\ C-夏普\ Automatic_Record \ Automatic_Record \ Automatic_Record \ Form1.cs中:行197
       在System.IO.FileSystemWatcher.OnChanged(FileSystemEventArgs E)
       在System.IO.FileSystemWatcher.NotifyFileSystemEventArgs(的Int32行动,字符串名称)
       在System.IO.FileSystemWatcher.CompletionStatusChanged(UInt32的错误code,UInt32的的numBytes,NativeOverlapped * overlappedPointer)
       在System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32的错误code,UInt32的的numBytes,NativeOverlapped * pOVERLAP)
  的InnerException:
 

解决方案

这是因为发生火灾FileSystemWatcher的多个onChanged事件,这对于任何一个变化。所以你禁用EnableRaisingEvent观察家之前可能发射多onChanged事件,这。你需要把使用TaskCompletionSource.SetResult使用TaskCompletionSource.TrySetResult的锁定在你的OnChanged方法或替代。

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

I have a watcher method i'm calling from the constructor of 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;
        } 

Then the Onchanged event:

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();
                }
        }

And this is the IsFileLocked method:

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();
            }

And i'm using it in this method:

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

The exception is in the OnChanged event on the line:

sy.SetResult(true);

sy is:

TaskCompletionSource<bool> sy;

In the OnChanged method i did:

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

But still getting sometimes the exception. The exception is:

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: 

解决方案

This is happening because FileSystemWatcher fire multiple onChanged event for any single change. So before you disable EnableRaisingEvent watcher could have fired multiple onChanged event. You need to put locking in your onChanged method or instead of using TaskCompletionSource.SetResult use TaskCompletionSource.TrySetResult.

See this for details on TrySetResult: https://msdn.microsoft.com/en-us/library/dd449176(v=vs.110).aspx

这篇关于我一直有时变得异常的System.Threading.Tasks.TaskCompletionSource&LT;布尔&GT;我该如何解决呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆