Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使该方法首先返回一个字符串,然后继续代码的其余部分?_C#_.net_Winforms - Fatal编程技术网

C# 如何使该方法首先返回一个字符串,然后继续代码的其余部分?

C# 如何使该方法首先返回一个字符串,然后继续代码的其余部分?,c#,.net,winforms,C#,.net,Winforms,我有一个web服务器,我添加了以下方法: public async Task<string> SendResponseAsync(HttpListenerRequest request)//public string SendResponse(HttpListenerRequest request) { string result = ""; string key = request.QueryString.GetKey

我有一个web服务器,我添加了以下方法:

public async Task<string> SendResponseAsync(HttpListenerRequest request)//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 = "";
                            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);
                    uploadedFilesList.Add(fileforupload);
                    Youtube_Uploader youtubeupload = new Youtube_Uploader(fileforupload);//uploadedFilesList[0]);
                }
            }
            else
            {
                result = "Nothing have been done";
            }
            return result;
        }
问题是,在完成等待之前,它不会返回结果。 但我需要让它先返回结果,然后再返回其他结果

这是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;
            }
        }
更新:

这就是我在form1构造函数中创建Web服务器实例并使用SendResponseAsync方法的方式

var ws = new WebServer(
            request => Task.Run(() => SendResponseAsync(request)),
            "http://+:8098/");
这是WebServer类:

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, Task<string>> _responderMethod;

        public WebServer(string[] prefixes, Func<HttpListenerRequest, Task<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, Task<string>> method, params string[] prefixes)
            : this(prefixes, method) { }

        public void Run()
        {
            ThreadPool.QueueUserWorkItem((o) =>
            {
                Console.WriteLine("Webserver running...");
                try
                {
                    while (_listener.IsListening)
                    {
                        ThreadPool.QueueUserWorkItem(async (c) =>
                        {
                            var ctx = c as HttpListenerContext;
                            try
                            {
                                string rstr = await _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 (Exception error)
                            {

                                string ttt = error.ToString();
                            } // 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();
        }
    }
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
Net系统;
使用系统线程;
名称空间自动记录
{
类Web服务器
{
私有只读HttpListener _listener=new HttpListener();
私有只读函数响应方法;
公共Web服务器(字符串[]前缀,Func方法)
{
如果(!HttpListener.IsSupported)
抛出新的NotSupportedException(
“需要Windows XP SP2、Server 2003或更高版本。”);
//例如,URI前缀是必需的
// "http://localhost:8080/index/".
if(前缀==null | |前缀.长度==0)
抛出新的ArgumentException(“前缀”);
//需要响应者方法
if(方法==null)
抛出新的ArgumentException(“方法”);
foreach(前缀中的字符串s)
_listener.Prefixes.Add(s);
_responderMethod=方法;
_listener.Start();
}
公共Web服务器(Func方法,参数字符串[]前缀)
:this(前缀、方法){}
公开募捐
{
ThreadPool.QueueUserWorkItem((o)=>
{
WriteLine(“正在运行的Web服务器…”);
尝试
{
while(_listener.IsListening)
{
ThreadPool.QueueUserWorkItem(异步(c)=>
{
var ctx=c作为HttpListenerContext;
尝试
{
字符串rstr=wait_responderMethod(ctx.Request);
系统.诊断.跟踪.写入(ctx.请求.查询字符串);
//ctx.Request.QueryString
字节[]buf=Encoding.UTF8.GetBytes(rstr);
ctx.Response.ContentLength64=基本长度;
ctx.Response.OutputStream.Write(buf,0,buf.Length);
System.Data.SqlClient.SqlConnectionStringBuilder builder=new System.Data.SqlClient.SqlConnectionStringBuilder();
}
捕获(异常错误)
{
字符串ttt=error.ToString();
}//禁止任何异常
最后
{
//始终关闭小溪
ctx.Response.OutputStream.Close();
}
},_listener.GetContext());
}
}
catch{}//禁止任何异常
});
}
公共停车场()
{
_listener.Stop();
_listener.Close();
}
}

如果我理解正确,在
SendResponseAsync()
方法的操作过程中,您有多个“检查点”,并且在每个检查点上,您都希望能够向客户端发送带有某些状态消息的响应(例如,您希望报告结果
“录制已停止,并准备在youtube上共享文件”
在调用
WatchDirectory()
完成之后,但在执行调用
WaitForUnlockedFile()
之前

基本问题是
SendResponseAsync()
方法可以像任何其他方法
async
或其他方法一样,只返回一个值。任何方法都不能返回一次以上†,对于
async
方法和任何其他类型的方法一样

那么,该怎么办呢?好吧,如果不在上下文中查看代码(即,如果没有可靠地再现您的问题),就不可能确定。但是C#中的一种惯用方法是使用
IProgress
接口,允许用状态值回调方法的调用方,以便它能够适当地处理它们(例如,发送给客户)

例如,您可以将方法更改为如下所示:

public async Task SendResponseAsync(
        HttpListenerRequest request, IProgress<string> progress)
    {
        string key = request.QueryString.GetKey(0);
        if (key == "cmd")
        {
            if (request.QueryString[0] == "uploadstatus")
            {
                switch (Youtube_Uploader.uploadstatus)
                {
                    case "uploading file":
                        progress.Report("uploading " + Youtube_Uploader.fileuploadpercentages);
                        return;

                    case "status":
                        progress.Report(Youtube_Uploader.fileuploadpercentages.ToString());
                        return;

                    case "file uploaded successfully":
                        Youtube_Uploader.uploadstatus = "";
                        Youtube_Uploader.fileuploadpercentages + ","
                           + Youtube_Uploader.time;

                    default:
                        progress.Report("upload unknown state");
                        return;
                }     
            }
            if (request.QueryString[0] == "nothing")
            {
                progress.Report("Connection Success");
                return;
            }
            if (request.QueryString[0] == "start")
            {
                StartRecrod();
                progress.Report("Recording started");
            }
            if (request.QueryString[0] == "stop")
            {
                dirchanged = false;
                StartRecrod();
                string fileforupload = await WatchDirectory();
                progress.Report("Recording stopped and preparing the file to be shared on youtube");
                await WaitForUnlockedFile(fileforupload);
                uploadedFilesList.Add(fileforupload);
                Youtube_Uploader youtubeupload = new Youtube_Uploader(fileforupload);//uploadedFilesList[0]);
            }
        }
        else
        {
            progress.Report("Nothing have been done");
        }
    }
string result = await SendResponseAsync(request);

SendResultToClient(result);
await SendResponseAsync(request, new Progress<string>(s => SendResultToClient(s)));
var ws = new WebServer(SendResponseAsync, "http://+:8098/");
然后您可以调用该方法的新版本,如下所示:

public async Task SendResponseAsync(
        HttpListenerRequest request, IProgress<string> progress)
    {
        string key = request.QueryString.GetKey(0);
        if (key == "cmd")
        {
            if (request.QueryString[0] == "uploadstatus")
            {
                switch (Youtube_Uploader.uploadstatus)
                {
                    case "uploading file":
                        progress.Report("uploading " + Youtube_Uploader.fileuploadpercentages);
                        return;

                    case "status":
                        progress.Report(Youtube_Uploader.fileuploadpercentages.ToString());
                        return;

                    case "file uploaded successfully":
                        Youtube_Uploader.uploadstatus = "";
                        Youtube_Uploader.fileuploadpercentages + ","
                           + Youtube_Uploader.time;

                    default:
                        progress.Report("upload unknown state");
                        return;
                }     
            }
            if (request.QueryString[0] == "nothing")
            {
                progress.Report("Connection Success");
                return;
            }
            if (request.QueryString[0] == "start")
            {
                StartRecrod();
                progress.Report("Recording started");
            }
            if (request.QueryString[0] == "stop")
            {
                dirchanged = false;
                StartRecrod();
                string fileforupload = await WatchDirectory();
                progress.Report("Recording stopped and preparing the file to be shared on youtube");
                await WaitForUnlockedFile(fileforupload);
                uploadedFilesList.Add(fileforupload);
                Youtube_Uploader youtubeupload = new Youtube_Uploader(fileforupload);//uploadedFilesList[0]);
            }
        }
        else
        {
            progress.Report("Nothing have been done");
        }
    }
string result = await SendResponseAsync(request);

SendResultToClient(result);
await SendResponseAsync(request, new Progress<string>(s => SendResultToClient(s)));
var ws = new WebServer(SendResponseAsync, "http://+:8098/");
那么构造函数调用应该如下所示:

public async Task SendResponseAsync(
        HttpListenerRequest request, IProgress<string> progress)
    {
        string key = request.QueryString.GetKey(0);
        if (key == "cmd")
        {
            if (request.QueryString[0] == "uploadstatus")
            {
                switch (Youtube_Uploader.uploadstatus)
                {
                    case "uploading file":
                        progress.Report("uploading " + Youtube_Uploader.fileuploadpercentages);
                        return;

                    case "status":
                        progress.Report(Youtube_Uploader.fileuploadpercentages.ToString());
                        return;

                    case "file uploaded successfully":
                        Youtube_Uploader.uploadstatus = "";
                        Youtube_Uploader.fileuploadpercentages + ","
                           + Youtube_Uploader.time;

                    default:
                        progress.Report("upload unknown state");
                        return;
                }     
            }
            if (request.QueryString[0] == "nothing")
            {
                progress.Report("Connection Success");
                return;
            }
            if (request.QueryString[0] == "start")
            {
                StartRecrod();
                progress.Report("Recording started");
            }
            if (request.QueryString[0] == "stop")
            {
                dirchanged = false;
                StartRecrod();
                string fileforupload = await WatchDirectory();
                progress.Report("Recording stopped and preparing the file to be shared on youtube");
                await WaitForUnlockedFile(fileforupload);
                uploadedFilesList.Add(fileforupload);
                Youtube_Uploader youtubeupload = new Youtube_Uploader(fileforupload);//uploadedFilesList[0]);
            }
        }
        else
        {
            progress.Report("Nothing have been done");
        }
    }
string result = await SendResponseAsync(request);

SendResultToClient(result);
await SendResponseAsync(request, new Progress<string>(s => SendResultToClient(s)));
var ws = new WebServer(SendResponseAsync, "http://+:8098/");
当然,您已经修改了
SendResponseAsync()
,正如我上面解释的那样,这样它就可以接收
IProgress
的实例作为参数

完成所有这些之后,您的
WebServer
类的
Run()中的代码块
将结果文本写入响应输出流的方法封装在一个匿名方法中,该方法用作传递给
\u responseMethod
委托调用的
进度
实例的
委托

注意:

上述内容在您的场景中可能是正确的,也可能是不正确的。同样,如果没有一个好的代码示例,也不可能确定。但是请记住,
进度
类在创建时使用当前的
同步上下文
来引发其
进度更改
事件。在许多情况下,这正是您想要的。但根据此处调用的上下文,这是可能的