我如何使用方法异步任务<字符串>并返回字符串,然后我如何通过一个委托的方法来构造和以后使用它?字符串、方法来、使用方法、任务

2023-09-03 06:02:39 作者:倚栏听风

我有这样的方法,它返回字符串

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>

推荐答案

随着回答者的