【发布时间】:2015-08-11 04:43:50
【问题描述】:
在构造函数中,我正在调用 WatchDirectory 方法:
private void WatchDirectory()
{
FileSystemWatcher 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)
{
try
{
var info = new FileInfo(e.FullPath);
fileforupload = info.FullName;
if (e.ChangeType == WatcherChangeTypes.Changed)
{
var theSize = info.Length;
label2.BeginInvoke((Action)(() =>
{
label2.Text = theSize.ToString();
}));
}
dirchanged = true;
}
catch (Exception ee)
{
string err = ee.ToString();
}
}
然后我使用 while 循环来检查 dirchange 标志何时为真:
WatchDirectory();
while (dirchanged == false)
{
if (dirchanged == true)
{
Youtube_Uploader youtubeupload = new
Youtube_Uploader(fileforupload);
break;
}
}
问题在于,有时它永远不会在 OnChanged 事件中将 dirchanged 更改为 true。不知道为什么。它似乎触发了 OnChanged 事件,但有时它不执行 dirchanged = true;
因此在while 循环内dirchanged 标志始终保持false。
我现在添加了一个新方法,我称之为 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();
}
return false;
}
我在 OnChanged 事件中使用它:
private void OnChanged(object source, FileSystemEventArgs e)
{
try
{
var info = new FileInfo(e.FullPath);
fileforupload = info.FullName;
IsFileLocked(info);
if (e.ChangeType == WatcherChangeTypes.Changed)
{
var theSize = info.Length;
label2.BeginInvoke((Action)(() =>
{
label2.Text = theSize.ToString();
}));
}
dirchanged = true;
}
catch (Exception ee)
{
string err = ee.ToString();
}
}
在 IsFileLocked 方法中,我遇到了异常:
该进程无法访问文件“C:\Users\bout0_000\Videos\My Great Game - My Great Capture - 2015-08-10 14-22-52.mp4”,因为它正被另一个进程使用。
我正在使用创建文件的外部程序,由于该程序仍在创建文件,因此观察者无法访问它。 所以我在这里有一个冲突,一方面我想知道文件何时完成创建,但另一方面我不知道,因为外部程序仍在处理它。
那么我怎样才能知道外部程序何时完成对文件的处理并且文件准备好了?
这是while代码的全部部分:
if (request.QueryString[0] == "stop")
{
dirchanged = false;
StartRecrod();
result = "Recording stopped and preparing the file to be shared on youtube";
WatchDirectory();
while (dirchanged == false)
{
if (dirchanged == true)
{
string ttttt = "ok";
break;
}
}
}
我添加了一个字符串 ttttt 只是为了测试。 有时在使用断点时会到达字符串 ttttt,有时不会。
在我的程序中,当我触摸我的 android 屏幕时,它会向 pc 网络服务器发送命令,它会到达这里,但是 while 循环有问题,并且有时会更改标志,它确实会进入 while 和 IF 并执行字符串 ttttt有时不会。
这就是我现在对 await 所做的:
TaskCompletionSource<bool> sy;
public async void SendResponse(HttpListenerRequest request)
{
string result = "";
string key = request.QueryString.GetKey(0);
if (key == "cmd")
{
if (request.QueryString[0] == "nothing")
{
return "Connection Success";
}
if (request.QueryString[0] == "start")
{
StartRecrod();
result = "Recording started";
}
if (request.QueryString[0] == "stop")
{
dirchanged = false;
StartRecrod();
result = "Recording stopped and preparing the file to be shared on youtube";
sy = new TaskCompletionSource<bool>();
WatchDirectory();
await sy.Task;
Youtube_Uploader youtubeupload = new Youtube_Uploader(fileforupload);
}
}
else
{
result = "Nothing have been done";
}
if (Youtube_Uploader.fileuploadedsuccess != null && Youtube_Uploader.fileuploadedsuccess != "")
{
result = Youtube_Uploader.fileuploadedsuccess;
}
return result;
}
但是有些问题。 首先,我在所有退货中都遇到了错误。
错误 2 由于 'Automatic_Record.Form1.SendResponse(System.Net.HttpListenerRequest)' 返回 void,return 关键字后面不能跟对象表达式
初始化我的网络服务器时出错:
WebServer ws = new WebServer(SendResponse, "http://+:8098/");
在我得到的 SendResponse 上:
错误 1 'void Automatic_Record.Form1.SendResponse(System.Net.HttpListenerRequest)' 的返回类型错误
现在将方法更改为异步时会发生此错误。
这是我的 WebServer 方法,我在初始化时出错,因为它应该得到其他东西然后异步:
public WebServer(Func<HttpListenerRequest, string> method, params string[] prefixes)
: this(prefixes, method) { }
public void Run()
{
ThreadPool.QueueUserWorkItem((o) =>
{
Console.WriteLine("Webserver running...");
try
{
while (_listener.IsListening)
{
ThreadPool.QueueUserWorkItem((c) =>
{
var ctx = c as HttpListenerContext;
try
{
string rstr = _responderMethod(ctx.Request);
System.Diagnostics.Trace.Write(ctx.Request.QueryString);
//ctx.Request.QueryString
byte[] buf = Encoding.UTF8.GetBytes(rstr);
ctx.Response.ContentLength64 = buf.Length;
ctx.Response.OutputStream.Write(buf, 0, buf.Length);
System.Data.SqlClient.SqlConnectionStringBuilder builder = new System.Data.SqlClient.SqlConnectionStringBuilder();
}
catch { } // suppress any exceptions
finally
{
// always close the stream
ctx.Response.OutputStream.Close();
}
}, _listener.GetContext());
}
}
catch { } // suppress any exceptions
});
}
【问题讨论】:
-
好吧,您是否尝试在异常捕获中设置断点?因为像现在这样,你永远不会知道是否抛出了异常,因为你只是创建了一个新字符串,但什么也没做。
-
我添加了一个新方法 IsFileLocked 并在 OnChanged 事件中使用它,我也用它更新了我的问题。我发现我的观察者与在硬盘上创建文件的外部程序发生冲突。我对观察者的主要想法是检查文件大小的变化,如果没有变化,那么文件就可以上传了。但问题是观察者冲突,因为外部程序正在构建文件。
-
我还能如何判断文件是否准备好?我想在外部程序完成文件制作后自动上传到 youtube。所以我使用标志 while 和 watcher 但在某些情况下 watcher 与外部程序冲突。
-
也许 IsFileLocked 方法我在 OnChanged 中使用错误?现在我只是打电话给它,但也许我应该用它做点别的?
-
好的,我将方法更改为 public async Task
所以现在修复了两个错误,但我仍然在初始化 Web 服务器的构造函数中遇到错误: WebServer ws = new WebServer(SendResponse, "http://+:8098/");错误:错误 1 'System.Threading.Tasks.Task Automatic_Record.Form1.SendResponse(System.Net.HttpListenerRequest)' 返回类型错误,这是 WebServer 的方法:public WebServer(Func 方法,参数字符串 [] 前缀)我该如何解决这个错误?