Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.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/2/.net/25.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_Task_Task Parallel Library_Wait - Fatal编程技术网

如何等待任务在C#中完成?

如何等待任务在C#中完成?,c#,.net,task,task-parallel-library,wait,C#,.net,Task,Task Parallel Library,Wait,我想向服务器发送请求并处理返回的值: private static string Send(int id) { Task<HttpResponseMessage> responseTask = client.GetAsync("aaaaa"); string result = string.Empty; responseTask.ContinueWith(x => result = Print(x)); responseTask.Wait();

我想向服务器发送请求并处理返回的值:

private static string Send(int id)
{
    Task<HttpResponseMessage> responseTask = client.GetAsync("aaaaa");
    string result = string.Empty;
    responseTask.ContinueWith(x => result = Print(x));
    responseTask.Wait(); // it doesn't wait for the completion of the response task
    return result;
}

private static string Print(Task<HttpResponseMessage> httpTask)
{
    Task<string> task = httpTask.Result.Content.ReadAsStringAsync();
    string result = string.Empty;
    task.ContinueWith(t =>
    {
        Console.WriteLine("Result: " + t.Result);
        result = t.Result;
    });
    task.Wait();  // it does wait
    return result;
}
私有静态字符串发送(int-id)
{
Task-responseTask=client.GetAsync(“aaaaa”);
字符串结果=string.Empty;
responseTask.ContinueWith(x=>result=Print(x));
responseTask.Wait();//它不等待响应任务的完成
返回结果;
}
私有静态字符串打印(任务httpTask)
{
Task Task=httpTask.Result.Content.ReadAsStringAsync();
字符串结果=string.Empty;
task.ContinueWith(t=>
{
Console.WriteLine(“结果:+t.Result”);
结果=t.结果;
});
task.Wait();//它确实在等待
返回结果;
}
我是否正确使用
任务
?我不这么认为,因为
Send()
方法每次都返回
string.Empty
,而
Print
返回正确的值


我做错了什么?如何从服务器获得正确的结果?

它等待
client.GetAsync(“aaaaaa”),但不等待
结果=打印(x)

尝试
responseTask.ContinueWith(x=>result=Print(x)).Wait()

--编辑--

以上代码不能保证输出:

In task
In ContinueWith
End
但确实如此(请参见
newTask


您的Print方法可能需要等待continuation完成(continuateWith返回一个您可以等待的任务)。否则,第二个ReadAsStringAsync将完成,该方法将返回(在继续中指定结果之前)。发送方法中也存在相同的问题。这两种方法都需要等待后续操作,才能始终如一地获得所需的结果。如下所示

private static string Send(int id)
{
    Task<HttpResponseMessage> responseTask = client.GetAsync("aaaaa");
    string result = string.Empty;
    Task continuation = responseTask.ContinueWith(x => result = Print(x));
    continuation.Wait();
    return result;
}

private static string Print(Task<HttpResponseMessage> httpTask)
{
    Task<string> task = httpTask.Result.Content.ReadAsStringAsync();
    string result = string.Empty;
    Task continuation = task.ContinueWith(t =>
    {
        Console.WriteLine("Result: " + t.Result);
        result = t.Result;
    });
    continuation.Wait();  
    return result;
}
私有静态字符串发送(int-id)
{
Task-responseTask=client.GetAsync(“aaaaa”);
字符串结果=string.Empty;
任务继续=响应任务。继续(x=>result=Print(x));
continuation.Wait();
返回结果;
}
私有静态字符串打印(任务httpTask)
{
Task Task=httpTask.Result.Content.ReadAsStringAsync();
字符串结果=string.Empty;
任务继续=任务。继续(t=>
{
Console.WriteLine(“结果:+t.Result”);
结果=t.结果;
});
continuation.Wait();
返回结果;
}

我是一个异步新手,所以我不能确切地告诉您这里发生了什么。我怀疑方法执行期望值不匹配,即使您在方法内部使用任务。我认为,如果更改打印以返回任务,您将获得预期的结果:

私有静态字符串发送(int-id)
{
Task-responseTask=client.GetAsync(“aaaaa”);
任务结果;
responseTask.ContinueWith(x=>result=Print(x));
result.Wait();
responseTask.Wait();//可能有更好的方法来等待这两个任务,而不必以这种笨拙、连续的方式进行。
返回结果。结果;
}
私有静态任务打印(任务httpTask)
{
Task Task=httpTask.Result.Content.ReadAsStringAsync();
字符串结果=string.Empty;
task.ContinueWith(t=>
{
Console.WriteLine(“结果:+t.Result”);
结果=t.结果;
});
返回任务;
}

在使用continuations时,我发现思考我的写作地点很有用。continuationWith是执行立即继续到它后面的语句的地方,而不是它“内部”的语句。在这种情况下,很明显,您将在Send中返回一个空字符串。如果您对响应的唯一处理是将其写入控制台,则在Ito的解决方案中不需要任何等待-控制台打印输出将在不等待的情况下进行,但在这种情况下,发送和打印都应返回void。在控制台应用程序中运行此程序,您将获得页面的打印输出

IMO、waits和Task.Result调用(哪个块)有时是必要的,这取决于您所需的控制流,但更常见的是,它们表明您没有真正正确地使用异步功能

namespace TaskTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Send();
            Console.WriteLine("Press Enter to exit");
            Console.ReadLine();
        }

        private static void Send()
        {
            HttpClient client = new HttpClient();
            Task<HttpResponseMessage> responseTask = client.GetAsync("http://google.com");
            responseTask.ContinueWith(x => Print(x));
        }

        private static void Print(Task<HttpResponseMessage> httpTask)
        {
            Task<string> task = httpTask.Result.Content.ReadAsStringAsync();
            Task continuation = task.ContinueWith(t =>
            {
                Console.WriteLine("Result: " + t.Result);
            });
        }
    }
}
namespace任务测试
{
班级计划
{
静态void Main(字符串[]参数)
{
Send();
控制台写入线(“按回车键退出”);
Console.ReadLine();
}
私有静态void Send()
{
HttpClient=新的HttpClient();
Task responseTask=client.GetAsync(“http://google.com");
responseTask.ContinueWith(x=>Print(x));
}
专用静态无效打印(任务httpTask)
{
Task Task=httpTask.Result.Content.ReadAsStringAsync();
任务继续=任务。继续(t=>
{
Console.WriteLine(“结果:+t.Result”);
});
}
}
}
异步任务访问WebAsync()
{   
//您需要添加对System.Net.Http的引用以声明客户端。
HttpClient=新的HttpClient();
//GetStringAsync返回一个任务。这意味着当您等待
//任务您将获得一个字符串(urlContents)。
任务getStringTask=
client.GetStringAsync(“http://msdn.microsoft.com");  
//您可以在这里执行不依赖GetStringAsync中的字符串的工作。
做独立的工作();
//wait运算符挂起对WebAsync的访问。
//-AccessTheWebAsync在getStringTask完成之前无法继续。
//-同时,控件返回给AccessTheWebAsync的调用方。
//-当getStringTask完成时,控件在此恢复。
//-然后,等待运算符从中检索字符串结果
getStringTask。
字符串urlContents=等待getStringTask;
//return语句指定一个整数结果。
//在此等待访问WebCenter代码的任何方法都将异步检索长度
价值
返回urlContents.Length;
}  

回答标题的清晰示例

string output = "Error";
Task task = Task.Factory.StartNew(() =>
{
    System.Threading.Thread.Sleep(2000);
    output = "Complete";
});

task.Wait();
Console.WriteLine(output);
但是我在Print()方法中调用task.Wait()。当您调用
task.Wait()
时,您会等待
private static string Send(int id)
{
    Task<HttpResponseMessage> responseTask = client.GetAsync("aaaaa");
    Task<string> result;
    responseTask.ContinueWith(x => result = Print(x));
    result.Wait();
    responseTask.Wait(); // There's likely a better way to wait for both tasks without doing it in this awkward, consecutive way.
    return result.Result;
}

private static Task<string> Print(Task<HttpResponseMessage> httpTask)
{
    Task<string> task = httpTask.Result.Content.ReadAsStringAsync();
    string result = string.Empty;
    task.ContinueWith(t =>
    {
        Console.WriteLine("Result: " + t.Result);
        result = t.Result;
    });
    return task;
}
namespace TaskTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Send();
            Console.WriteLine("Press Enter to exit");
            Console.ReadLine();
        }

        private static void Send()
        {
            HttpClient client = new HttpClient();
            Task<HttpResponseMessage> responseTask = client.GetAsync("http://google.com");
            responseTask.ContinueWith(x => Print(x));
        }

        private static void Print(Task<HttpResponseMessage> httpTask)
        {
            Task<string> task = httpTask.Result.Content.ReadAsStringAsync();
            Task continuation = task.ContinueWith(t =>
            {
                Console.WriteLine("Result: " + t.Result);
            });
        }
    }
}
async Task<int> AccessTheWebAsync()  
{   
    // You need to add a reference to System.Net.Http to declare client.  
    HttpClient client = new HttpClient();  

    // GetStringAsync returns a Task<string>. That means that when you await the  
    // task you'll get a string (urlContents).  
    Task<string> getStringTask = 

    client.GetStringAsync("http://msdn.microsoft.com");  

    // You can do work here that doesn't rely on the string from GetStringAsync.  
    DoIndependentWork();  

    // The await operator suspends AccessTheWebAsync.  
    //  - AccessTheWebAsync can't continue until getStringTask is complete.  
    //  - Meanwhile, control returns to the caller of AccessTheWebAsync.  
    //  - Control resumes here when getStringTask is complete.   
    //  - The await operator then retrieves the string result from 
    getStringTask.  
    string urlContents = await getStringTask;  

    // The return statement specifies an integer result.  
    // Any methods that are awaiting AccessTheWebenter code hereAsync retrieve the length 
    value.  
    return urlContents.Length;  
}  
string output = "Error";
Task task = Task.Factory.StartNew(() =>
{
    System.Threading.Thread.Sleep(2000);
    output = "Complete";
});

task.Wait();
Console.WriteLine(output);