我有一个ServiceInvoker,它调用Web API(POST端点)
public async Task<HttpResponseMessage> InvokeService(string url, string action)
{
string requestUri = @"api/MyController/" + action;
HttpResponseMessage response;
HttpClientHandler handler = new HttpClientHandler()
{
UseDefaultCredentials = true
};
using (var client = new HttpClient(handler))
{
client.BaseAddress = new Uri(url);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
response =await client.PostAsJsonAsync(requestUri, myObj);
}
return response;
}
当我调试时,PostAsJsonAsync
执行后,控件转到main()
。也没有调试我无法点击该服务。它在我这样做时起作用
response =client.PostAsJsonAsync(requestUri, myObj).Result;
但它是同步的。
此方法从main()
void main()
{
Start()
}
public void Start()
{
Process();
}
public async Task Process()
{
HttpResponseMessage servResponse;
servResponse=await InvokeService("http://myServiceUrl","myAction");
}
我的要求是从不同的应用程序中对服务进行大量调用。我想调用异步来提高性能。
答案 0 :(得分:2)
您没有等待Process()
完全执行 - 您只需触发异步操作,忘记它并返回:
Process();
您应该等待任务完成。 E.g。
Process().Wait();
应用程序在主线程终止时终止。你有多少背景线程并不重要。当主线程终止时,它们都将被自动杀死。因此,在后台线程正在执行其工作时,您有两个选项可以使应用程序保持活动状态:
让我们考虑第一个选择。如果有许多后台线程,那么您将拥有多线程异步应用程序。主线程被阻止,但还有许多其他线程并行执行。但是如果你有单一的后台线程怎么办?主要是等待它,你有多线程同步应用程序。这是你的理由。
现在第二个选项。在后台线程执行时在主线程上执行某些操作 - 是使用异步操作的重点。 但你的应用程序与主线程无关。当然你可以模拟一些工作。即使有像
这样的东西Process(); // fire and forget
while (true); // make your main thread busy
这将使您的应用程序成为多线程和异步的。但主线程将忙于消耗CPU资源。没有其他的。如果你在主线上有一些真实的东西:
var task = Process();
DoSomeRealJobHere();
task.Wait(); // still you need to wait for background task
或者,如果您希望应用程序更具互动性
var task = Process();
do
{
DoSomethingHere(); // e.g display current weather info
} while (!task.IsCompleted);
注意:如果您使用的是异步操作,请考虑通过传递CancelationToken来提供取消它们的选项。