我有这样的方法,它返回字符串
:
I have this method that returns string
:
public string SendResponse(HttpListenerRequest request)
{
string result = "";
string key = request.QueryString.GetKey(0);
if (key == "cmd")
{
if (request.QueryString[0] == "uploadstatus")
{
switch (Youtube_Uploader.uploadstatus)
{
case "uploading file":
return "uploading " + Youtube_Uploader.fileuploadpercentages;
case "status":
return Youtube_Uploader.fileuploadpercentages.ToString();
case "file uploaded successfully":
Youtube_Uploader.uploadstatus = "";
return "upload completed," + Youtube_Uploader.fileuploadpercentages + ","
+ Youtube_Uploader.time;
default:
return "upload unknown state";
}
}
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";
string fileforupload = await WatchDirectory();
await WaitForUnlockedFile(fileforupload);
using (StreamWriter w = new StreamWriter(userVideosDirectory + "\\UploadedVideoFiles.txt", true))
{
w.WriteLine(fileforupload);
}
uploadedFilesList.Add(fileforupload);
Youtube_Uploader youtubeupload = new Youtube_Uploader(uploadedFilesList[0]);
}
}
else
{
result = "Nothing have been done";
}
return result;
}
现在的问题是,在这个方法我用两行等待
:
string fileforupload = await WatchDirectory();
await WaitForUnlockedFile(fileforupload);
和让这两行的错误。这两个两个错误是一样的:
And getting errors on these two lines. Both two errors are the same:
错误'等待'运算符只能异步方法中使用。
考虑标志着这种方法与异步修改和改变
它的返回类型为任务<字符串>
Error The 'await' operator can only be used within an async method.
Consider marking this method with the 'async' modifier and changing
its return type to 'Task<string>'
.
如果有可能使 SendResponse()
方法,因为我需要它,并用返回的字符串的问题等待
?
The question if it's possible to make the SendResponse()
method to return string since I need it and also to use the await
?
这是两种方法,这就是为什么我需要使用等待
在 SendResponse()
方法:
This is the two methods that's why I need to use await
in the SendResponse()
method:
private async Task<string> WatchDirectory()
{
using (FileSystemWatcher watcher = new FileSystemWatcher())
{
TaskCompletionSource<string> tcs = new TaskCompletionSource<string>();
watcher.Path = userVideosDirectory;
watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size;
watcher.Filter = "*.mp4";
watcher.Changed += (sender, e) => tcs.SetResult(e.FullPath);
watcher.EnableRaisingEvents = true;
return await tcs.Task;
}
}
// You can get rid of the OnChanged() method altogether
private async Task WaitForUnlockedFile(string fileName)
{
while (true)
{
try
{
using (IDisposable stream = File.Open(fileName, FileMode.OpenOrCreate,
FileAccess.ReadWrite, FileShare.None))
{ /* on success, immediately dispose object */ }
break;
}
catch (IOException)
{
// ignore exception
// NOTE: for best results, consider checking the hresult value of
// the exception, to ensure that you are only ignoring the access violation
// exception you're expecting, rather than other exceptions, like
// FileNotFoundException, etc. which could result in a hung process
}
// You might want to consider a longer delay...maybe on the order of
// a second or two at least.
await Task.Delay(100);
}
}
更新:
我改变了方法 SendResponse()
是异步任务&LT;字符串&GT;
但随后在 Web服务器
类的构造函数我有这个并在此行收到错误:
I changed the method SendResponse()
to be async Task<string>
But then in the WebServer
class constructor I have this and getting error on this line:
WebServer ws = new WebServer(SendResponseAsync, "http://+:8098/");
(SendResponseAsync是SendResponse更名)
(SendResponseAsync is the SendResponse changed its name)
该错误是:
错误1'System.Threading.Tasks.Task Automatic_Record.Form1.SendResponseAync(System.Net.HttpListenerRequest)有错误的返回类型
Error 1 'System.Threading.Tasks.Task Automatic_Record.Form1.SendResponseAync(System.Net.HttpListenerRequest)' has the wrong return type
和Web服务器类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Threading;
namespace Automatic_Record
{
class WebServer
{
private readonly HttpListener _listener = new HttpListener();
private readonly Func<HttpListenerRequest, string> _responderMethod;
public WebServer(string[] prefixes, Func<HttpListenerRequest, string> method)
{
if (!HttpListener.IsSupported)
throw new NotSupportedException(
"Needs Windows XP SP2, Server 2003 or later.");
// URI prefixes are required, for example
// "http://localhost:8080/index/".
if (prefixes == null || prefixes.Length == 0)
throw new ArgumentException("prefixes");
// A responder method is required
if (method == null)
throw new ArgumentException("method");
foreach (string s in prefixes)
_listener.Prefixes.Add(s);
_responderMethod = method;
_listener.Start();
}
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
});
}
public void Stop()
{
_listener.Stop();
_listener.Close();
}
}
}
更新2
我想彼得的解决方案,所以我改变了Web Server类code到一个彼得展现在这个问题的解决方案。
I tried peter solution so i changed the WebServer class code to the one Peter show in this question solution.
然后在Form1构造函数中我做的:
Then in form1 constructor i did:
var ws = new WebServer(
() => Task.Run(request => SendResponseAsync(request)),
"http://+:8098/");
ws.Run();
然后,该方法SendResponseAsync:
Then the method SendResponseAsync:
public async Task<string> SendResponseAsync(HttpListenerRequest request)
{
string result = "";
string key = request.QueryString.GetKey(0);
if (key == "cmd")
{
if (request.QueryString[0] == "uploadstatus")
{
switch (Youtube_Uploader.uploadstatus)
{
case "uploading file":
return "uploading " + Youtube_Uploader.fileuploadpercentages;
case "status":
return Youtube_Uploader.fileuploadpercentages.ToString();
case "file uploaded successfully":
Youtube_Uploader.uploadstatus = "";
return "upload completed," + Youtube_Uploader.fileuploadpercentages + ","
+ Youtube_Uploader.time;
default:
return "upload unknown state";
}
}
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";
string fileforupload = await WatchDirectory();
await WaitForUnlockedFile(fileforupload);
using (StreamWriter w = new StreamWriter(userVideosDirectory + "\\UploadedVideoFiles.txt", true))
{
w.WriteLine(fileforupload);
}
uploadedFilesList.Add(fileforupload);
Youtube_Uploader youtubeupload = new Youtube_Uploader(uploadedFilesList[0]);
}
}
else
{
result = "Nothing have been done";
}
return result;
}
在WatchDirectory:
The WatchDirectory:
private async Task<string> WatchDirectory()
{
using (FileSystemWatcher watcher = new FileSystemWatcher())
{
TaskCompletionSource<string> tcs = new TaskCompletionSource<string>();
watcher.Path = userVideosDirectory;
watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size;
watcher.Filter = "*.mp4";
watcher.Changed += (sender, e) => tcs.SetResult(e.FullPath);
watcher.EnableRaisingEvents = true;
return await tcs.Task;
}
}
和持续的WaitForUnlockedFile
And last the WaitForUnlockedFile
private async Task WaitForUnlockedFile(string fileName)
{
while (true)
{
try
{
using (IDisposable stream = File.Open(fileName, FileMode.OpenOrCreate,
FileAccess.ReadWrite, FileShare.None))
{ /* on success, immediately dispose object */ }
break;
}
catch (IOException)
{
// ignore exception
// NOTE: for best results, consider checking the hresult value of
// the exception, to ensure that you are only ignoring the access violation
// exception you're expecting, rather than other exceptions, like
// FileNotFoundException, etc. which could result in a hung process
}
// You might want to consider a longer delay...maybe on the order of
// a second or two at least.
await Task.Delay(100);
}
}
不过就行收到错误:
But getting error on the line:
Task.Run 严重性code说明项目文件行错误无法将拉姆达EX pression键入字符串[]',因为它不是一个委托类型Automatic_Record
Task.Run Severity Code Description Project File Line Error Cannot convert lambda expression to type 'string[]' because it is not a delegate type Automatic_Record
和同样的错误就行了的http:// +:8098 / 严重性code说明项目文件行错误参数2:无法从串到System.Func>转换
And also error on the line "http://+:8098/" Severity Code Description Project File Line Error Argument 2: cannot convert from 'string' to 'System.Func>
随着回答者的