Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.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#_Multithreading_Asynchronous_Async Await_Task - Fatal编程技术网

C# 任务。运行它的工作方式

C# 任务。运行它的工作方式,c#,multithreading,asynchronous,async-await,task,C#,Multithreading,Asynchronous,Async Await,Task,我想这很简单,但我在工作中有一些误解 当我调用下面的代码时,它工作得很好,我大约在1秒内得到一个结果 return Task.Run(() => SendRequest<IADsystem[]>(path)).Result; returntask.Run(()=>SendRequest(path)).Result; 但这个永远不会返回结果: Task<IADsystem[]> task = SendRequest<IADsystem[]>(pat

我想这很简单,但我在工作中有一些误解

当我调用下面的代码时,它工作得很好,我大约在1秒内得到一个结果

return Task.Run(() => SendRequest<IADsystem[]>(path)).Result;
returntask.Run(()=>SendRequest(path)).Result;
但这个永远不会返回结果:

  Task<IADsystem[]> task = SendRequest<IADsystem[]>(path);
  task.Wait(); //also tried without wait
  return task.Result;
Task Task=SendRequest(路径);
task.Wait()//我也迫不及待地试了一下
返回任务。结果;
我想可能任务没有启动,我需要调用start(),但当我启动时,出现了“承诺式任务可能不会调用start”异常

发送请求方法:

 private async Task<T> SendRequest<T>(string requestUri) where T : class
    {
        var authHandler = new HttpClientHandler();
        authHandler.Credentials = CredentialCache.DefaultNetworkCredentials;

        using(var client = new HttpClient(authHandler))
        {
            client.BaseAddress = apiServerURI;
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(jsonAcceptType);

            HttpResponseMessage response = await client.GetAsync(requestUri);
            if (response.IsSuccessStatusCode)
            {
                return await response.Content.ReadAsAsync<T>();
            }
            else
                return null;
        }
    }
私有异步任务SendRequest(字符串requestUri),其中T:class
{
var authHandler=new-HttpClientHandler();
authHandler.Credentials=CredentialCache.DefaultNetworkCredentials;
使用(var client=newhttpclient(authHandler))
{
client.BaseAddress=apiServerURI;
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(jsonAcceptType);
HttpResponseMessage response=wait client.GetAsync(requestUri);
if(响应。IsSuccessStatusCode)
{
return wait response.Content.ReadAsAsync();
}
其他的
返回null;
}
}

请解释它是如何工作的

异步/等待方法必须始终是异步/等待的。如果您使用的是Windows窗体,则任何包含调用SendRequest的代码的事件处理程序都必须标记为async。UI事件处理程序和SendRequest之间的每个方法也必须标记为async,并且必须等待它们。那你应该

var result = await SendRequest<IADsystem[]>(path);
var result=等待发送请求(路径);
就像法比奥建议的那样


是关于async/await的更多信息。

我在本页开始学习async,所以我认为这是一个很好的起点。我敦促你们看看执行上下文

说到你为什么会死锁,我会尽力解释的。调用
task.Wait()
时,基本上是告诉当前线程等待结果继续。因此,现在您的当前线程或执行上下文正在等待结果继续。让我们继续。调用
task.Wait()
时,输入了
private async task SendRequest(string requestUri).
方法,到达
return Wait response.Content.readasasasync()的时刻
您传递了当前的执行上下文,该上下文正在等待来自
SendRequest
的结果。现在,你处于死锁中。为什么?您的UI线程正在等待
SendRequest
的答复,以便
SendRequest
完成(或
return
),它需要访问UI线程,但您无法访问UI线程,因为它正在等待
SendRequest
完成,但要
SendRequest
完成,它需要访问UI线程….

首先考虑
Wait()
方法:

Task<IADsystem[]> task = SendRequest<IADsystem[]>(path);
task.Wait(); //also tried without wait
return task.Result;
有点。它“工作”的意义是它不会死锁。但是,这并不理想,因为它会在请求期间阻塞线程池线程。更好的解决方案是始终使用
async

但暂且不提这一点,它之所以有效,是因为它“走出”了调用上下文
Task.Run
在线程池线程(没有UI或ASP.NET请求上下文的线程)上执行
SendRequest
,因此
SendRequest
中的
wait
s在线程池线程上恢复。这就是为什么你的调用线程可以在没有死锁的情况下阻止它


但它仍然不应该阻碍这项任务;它应该等待它。

您是否尝试过等待发送请求(路径)您的
SendRequest
方法与多线程无关。您在哪里执行它,什么环境(控制台、Winforms、WPF、ASP:NET)?如果您从您输入的UI线程调用第二个方法deadlock@Fabio,ASP NET Web表单,具有等待相同结果-永不返回此行应工作
var result=wait SendRequest(路径)。你说的“永不回头”是什么意思?你是如何检查这一点的
return Task.Run(() => SendRequest<IADsystem[]>(path)).Result;