在UploadToServer
完全执行之前,控制权返回到main方法。我应该从Task.Run()
移除UploadToServer
还是明确地执行WaitAll
?
public class Uploader
{
async public Task<int> Upload(int i)
{
int incremented = 0;
var t = UploadToServer(i);
if (t != null)
{
incremented = await t;
}
return incremented;
}
async private Task<int> UploadToServer(int i)
{
int incremented = 0;
await Task.Run(() =>
{
//Console.ReadLine();
//Actual upload operation
incremented = i + 1;
});
return incremented;
}
}
class Program
{
static void Main(string[] args)
{
Uploader upl = new Uploader();
var res = upl.Upload(10).Result;
}
}
答案 0 :(得分:4)
当你await
async
方法时,控制权会被回馈给调用者。您所遇到的是正确的async
行为。
如果您不希望在执行操作时返回该方法,请执行同步。
如果您尝试做的是I / O绑定工作(比如将内容上传到服务器),请不要使用Task.Run
,因为I / O绑定会自然地暴露异步端点,从而消除了对不必要线程的需求这个过程。以HttpClient
为例,它展示了一堆XXXAsync
方法。
答案 1 :(得分:0)
以这种方式尝试
private Task<int> UploadToServer(int i)
{
int incremented = 0;
return Task.Run(() =>
{
//Console.ReadLine();
//Actual upload operation
return incremented = i + 1;
});
}
或以这种方式
private async Task<int> UploadToServer(int i)
{
return await Task.Run(() => DoSomething(i)).Wait();
}
private int DoSomething(int i)
{
//Console.ReadLine();
//Actual upload operation
return i+1;
}
请注意,这些示例并非特别有用。 认为背景线程应该过自己的生活。
在你的情况下,我想你可以使用框架的HttpClient
类的一些异步方法
实施例
private async Task<int> GetWebPageHtmlSizeAsync()
{
var client = new HttpClient();
var html = await client.GetAsync("http://www.test.com/");
return html.Length;
}
<强>更新强>
我已经测试了这段代码并且它运行了
static void Main(string[] args)
{
Uploader upl = new Uploader();
var res = upl.Upload(10).Result;
}
public class Uploader
{
async public Task<int> Upload(int i)
{
int incremented = 0;
var t = UploadToServer(i);
if (t != null)
{
incremented = await t;
}
return incremented;
}
private async Task<int> UploadToServer(int i)
{
return await Task.Run(() => DoSomething(i));
}
private int DoSomething(int i)
{
//Console.ReadLine();
//Actual upload operation
Thread.Sleep(2000);
return i + 1;
}
}
主程序在收到正确的值和控制权之前等待2秒。
查看这篇Should I expose asynchronous wrappers for synchronous methods?文章,了解何时以及如何使用异步方法。在您的具体示例中,您无法从task.run获得优势。我只提供了一个代码的工作示例。