我最近有一种情况,我有一个ASP.NET WebAPI控制器,需要在其action方法中对另一个REST服务执行两个Web请求.我编写了我的代码,将功能完全分离为单独的方法,看起来有点像这个例子:
public class FooController : ApiController
{
public IHttpActionResult Post(string value)
{
var results = PerformWebRequests();
// Do something else here...
}
private IEnumerable<string> PerformWebRequests()
{
var result1 = PerformWebRequest("service1/api/foo");
var result = PerformWebRequest("service2/api/foo");
return new string[] { result1, result2 };
}
private string PerformWebRequest(string api)
{
using (HttpClient client = new HttpClient())
{
// Call other web API and return value here...
}
}
}
Run Code Online (Sandbox Code Playgroud)
因为我使用的HttpClient所有Web请求都必须是异步的.我之前从未使用async/await,因此我开始天真地添加关键字.首先,我将async关键字添加到PerformWebRequest(string api)方法中,然后调用者抱怨该PerformWebRequests()方法必须async也是为了使用await …
.NET 4.5.1:看来,我无法使用CancellationTokenSource内置超时取消在任务内运行的阻塞方法.
class Program
{
static void Main(string[] args)
{
var cts = new System.Threading.CancellationTokenSource();
System.Console.CancelKeyPress += (s, e) =>
{
e.Cancel = true;
cts.Cancel();
};
MainAsync(args, cts.Token).Wait();
}
// MainAsync from http://stackoverflow.com/questions/9208921/async-on-main-method-of-console-app
static async Task MainAsync(string[] args, System.Threading.CancellationToken token)
{
Console.WriteLine("Starting MainAsync");
var cts = new System.Threading.CancellationTokenSource(3000);
var task = Task.Factory.StartNew(() =>
{
Console.WriteLine("Starting task...");
var t = new System.Net.Sockets.TcpClient();
var buffer = new byte[t.ReceiveBufferSize];
t.Connect(new System.Net.IPEndPoint(System.Net.IPAddress.Parse("127.0.0.1"), 1337));
Console.WriteLine("Recieving...");
t.Client.Receive(buffer);
Console.WriteLine("Finished Recieving...");
return true;
}, cts.Token);
var success = …Run Code Online (Sandbox Code Playgroud) 我正在学习如何在控制台应用程序中使用异步函数,但无法使Task.WhenAll等到所有任务完成.以下代码有什么问题?它同步工作.先感谢您.
static void Main(string[] args)
{
...
IncluiValores(...);
...
}
static async void IncluiValores(...)
{
Task<List<int>> res1 = att.GetAIDBAPI(att);
Task<List<int>> res2 = att.GetAIDBAPI(att2);
List<int>[] res = await Task.WhenAll(res1, res2);
...
}
Run Code Online (Sandbox Code Playgroud)
更新 - 功能定义:
public async Task<List<int>> GetAIDBAPI(Attributes attributes)
{
List<int> results = null;
Connections client0 = new Connections();
HttpClient client = client0.OpenAPIConnection(attributes.User[0], attributes.Pwd, attributes.Server, attributes.Chave, attributes.Server2);
HttpResponseMessage response = await client.PostAsJsonAsync("api/Attributes/ID/Bulk", attributes);
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
results = JsonConvert.DeserializeObject<dynamic>(content).ToObject<List<int>>();
}
else
{
var content = …Run Code Online (Sandbox Code Playgroud) 我有代码,它异步运行一些块。如何在不创建 LongTask() 和 LongOperationAsync() 函数的情况下使 LongOperation() 以“内联”方式(直接从 Main 方法)异步运行?
class Program
{
static void Main(string[] args)
{
LongOperationAsync();
Console.WriteLine("Main thread finished.");
Console.ReadKey();
}
static void LongOperation()
{
Thread.Sleep(3000);
Console.WriteLine("Work completed");
}
static Task LongTask()
{
return Task.Run(() => LongOperation());
}
static async void LongOperationAsync()
{
await LongTask();
Console.WriteLine("Callback triggered");
}
}
Run Code Online (Sandbox Code Playgroud)
UPD
我希望我做对了。我的意思是,我想让任何现有函数异步并在执行后添加一些操作而不添加任何新函数。似乎下面的解决方案正在起作用。
class Program
{
static void Main(string[] args)
{
((Action)(async () =>
{
await Task.Run(() => LongOperation());
Console.WriteLine("Then callback triggered");
}))();
Console.WriteLine("Main thread finished first.");
Console.ReadKey();
}
static …Run Code Online (Sandbox Code Playgroud) 我的一些代码有问题,特别是这部分。我正在调用一个async返回 a的方法Task<List<>>(无法返回常规列表,因为该方法是异步的)。但是,我无法将其转换为常规列表,这正是我所需要的。这甚至可能吗?如果是这样,有人可以帮忙吗?:)
static void Main(string[] args) {
Program p = new Program();
List<Product> products = p.getProducts();
}
public async Task<List<Product>> getProducts() {
// calling woocommerce api
MyRestApi rest = new MyRestApi("http://someurl.com/wp-json/wc/v2", "consumer key", "consumer secret");
WCObject wc = new WCObject(rest);
List<Product> products = await wc.Product.GetAll();
return await Task.Run(() => new List<Product>(products));
}
Run Code Online (Sandbox Code Playgroud) 我有一个程序,没有任何目的,但帮助我了解如何异步和等待工作.它是一个控制台应用程序,它解析XML并等待返回名称,无论是姓氏还是名字.这是代码:
static void Main(string[] args)
{
Task<string> name = GetFirstParsedName();
name.Wait();
if (name.IsCompleted)
{
Console.WriteLine(name.Result);
}
Console.ReadLine();
}
static async Task<string> GetFirstParsedName()
{
string xmlSnippet = @"<person>
<FirstName>Chamir</FirstName>
<Surname>Bodasing</Surname>
<Gender>Male</Gender>
<Nationality>South African</Nationality></person>";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlSnippet);
XmlParser xmlParser = new XmlParser();
Task<string> t_GetFirstName = xmlParser.GetFirstName(xmlDoc);
Task<string> t_GetSurname = xmlParser.GetSurname(xmlDoc);
Task<string> t_firstReturnedName = await Task.WhenAny(new Task<string>[] { t_GetFirstName, t_GetSurname });
string firstReturnedName = await t_firstReturnedName;
return firstReturnedName;
}
static async Task<string> GetFirstName(XmlDocument personXml)
{
string firstName = personXml.SelectSingleNode("//FirstName").InnerText;
await …Run Code Online (Sandbox Code Playgroud) 对于下面的代码(使用EdgeJS模块),我想等待异步方法Start完成后再写sw.Elapsed,我该怎么做?
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using EdgeJs;
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
///
[STAThread]
static void Main()
{
// Application.EnableVisualStyles();
// Application.SetCompatibleTextRenderingDefault(false);
// Application.Run(new Form1());
Stopwatch sw =new Stopwatch();
sw.Start();
Task.Run((Action)Start).Wait();
//wait for start to complete --- how should I do it??
sw.Stop();
Console.WriteLine(sw.Elapsed);
}
public static async void Start()
{
var func = Edge.Func(@"
var esprima = require('esprima'); …Run Code Online (Sandbox Code Playgroud) 我有四种方法。
以下是我的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace AsyncObservation
{
class Program
{
static void Main(string[] args)
{
preform();
}
public static async Task Working()
{
Console.WriteLine("Please wait, the program is running");
}
public static async Task Takingtime()
{
Console.WriteLine("This Program started");
Thread.Sleep(1000);
Console.WriteLine("The Program finished");
}
public static async void preform()
{
Task timer = Takingtime();
Task wait = Working();
}
}
}
Run Code Online (Sandbox Code Playgroud)
最后:我需要显示
This program started.
Please …Run Code Online (Sandbox Code Playgroud) 我正在尝试理解async/await并阅读了大量文章,但我仍然对同步/异步性质感到困惑.
我有以下测试控制台应用程序:
static void Main(string[] args)
{
var test = FooAsync();
Console.WriteLine("After FooAsync");
for (int i = 0; i < 100; i++)
Console.WriteLine("After that");
Console.ReadKey();
}
private static async Task FooAsync()
{
Console.WriteLine("Before delay");
await Task.Delay(1);
Console.WriteLine("After delay");
}
Run Code Online (Sandbox Code Playgroud)
代码提供了以下行的输出:
Before delay
After FooAsync
After that
After that
After that
After that
After delay
After that
.
.
Run Code Online (Sandbox Code Playgroud)
我知道async/await 不会创建一个单独的线程进行处理,并且当FooAsync到达该await Task.Delay(1)行时它将返回到Main该任务尚未完成的任务,但是,因为我们只在单个线程上运行可以有人解释什么触发FooAsync方法在Main之前的任意点恢复然后Main可以继续?
更新 我收回它,i3arnon和dariogriffo是正确的.代码确实使用了多个线程(正如我之前看到的那样,在调试器中查看或完成了kha建议的显而易见的事情).我对以下页面上的"线程"部分感到困惑,https://msdn.microsoft.com/en-us/library/hh191443.aspx#BKMK_Threads没有意识到"延续"实际上是指要继续运行的任务计划一旦"等待"的任务完成.
我有这个方法,我想异步运行,以便我可以在运行时做其他事情.它不依赖于任何其他Async方法(它不会调用另一个资源,下载文件或任何东西).我想避免使用new Task(),Task.Factory.StartTask()并且Task.Run()如果可能的话,.
是否可以异步运行此方法,使用整洁,可读的代码并且不显式使用Task?
如果不是,那么异步运行该方法的最简单方法是什么?
注意:请不要担心方法中的愚蠢逻辑 - 我把它煮成故意慢但不显示我的实际代码.
public static void main(string[] args)
{
RunMySlowLogic();
}
private void RunMySlowLogic()
{
while (true)
for (int i=0; i<100000000;i++)
if (i == new Random().Next(999))
return true;
}
Run Code Online (Sandbox Code Playgroud)
目前,我认为我需要将方法包装在lambda或Task中并将其标记为异步.等待去哪儿了?