我一直有时变得异常的System.Threading.Tasks.TaskCompletionSource&LT;布尔&GT;我该如何解决呢? [英] I keep getting exception sometimes on System.Threading.Tasks.TaskCompletionSource<bool> how can i solve it?
问题描述
我有一个观察者方法,我正在从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&LT;布尔&GT;();
WatchDirectory();
sy.Task.Wait();
Youtube_Uploader youtubeupload =新Youtube_Uploader(fileforupload);
返回false;
}
唯一的例外是在上线的onChanged事件,这:
sy.SetResult(真正的);
SY是:
TaskCompletionSource&LT;布尔&GT; 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屋!