我正在学习async/await,并遇到了需要同步调用异步方法的情况.我怎样才能做到这一点?
异步方法:
public async Task<Customers> GetCustomers()
{
return await Service.GetCustomersAsync();
}
Run Code Online (Sandbox Code Playgroud)
正常使用:
public async void GetCustomers()
{
customerList = await GetCustomers();
}
Run Code Online (Sandbox Code Playgroud)
我尝试过使用以下内容:
Task<Customer> task = GetCustomers();
task.Wait()
Task<Customer> task = GetCustomers();
task.RunSynchronously();
Task<Customer> task = GetCustomers();
while(task.Status != TaskStatus.RanToCompletion)
Run Code Online (Sandbox Code Playgroud)
我也从这里尝试了一个建议,但是当调度程序处于暂停状态时它不起作用.
public static void WaitWithPumping(this Task task)
{
if (task == null) throw new ArgumentNullException(“task”);
var nestedFrame = new DispatcherFrame();
task.ContinueWith(_ => nestedFrame.Continue = false);
Dispatcher.PushFrame(nestedFrame);
task.Wait();
}
Run Code Online (Sandbox Code Playgroud)
以下是调用的异常和堆栈跟踪RunSynchronously:
System.InvalidOperationException
消息:可能无法在未绑定到委托的任务上调用RunSynchronously.
InnerException:null
资料来源:mscorlib …
我正在使用完全异步的API客户端,也就是说,每个操作都返回Task或者Task<T>,例如:
static async Task DoSomething(int siteId, int postId, IBlogClient client)
{
await client.DeletePost(siteId, postId); // call API client
Console.WriteLine("Deleted post {0}.", siteId);
}
Run Code Online (Sandbox Code Playgroud)
使用C#5 async/await运算符,启动多个任务并等待它们全部完成的正确/最有效方法是什么:
int[] ids = new[] { 1, 2, 3, 4, 5 };
Parallel.ForEach(ids, i => DoSomething(1, i, blogClient).Wait());
Run Code Online (Sandbox Code Playgroud)
要么:
int[] ids = new[] { 1, 2, 3, 4, 5 };
Task.WaitAll(ids.Select(i => DoSomething(1, i, blogClient)).ToArray());
Run Code Online (Sandbox Code Playgroud)
由于API客户端在内部使用HttpClient,我希望这会立即发出5个HTTP请求,并在每个请求完成时写入控制台.
// let's say there is a list of 1000+ URLs
string[] urls = { "http://google.com", "http://yahoo.com", ... };
// now let's send HTTP requests to each of these URLs in parallel
urls.AsParallel().ForAll(async (url) => {
var client = new HttpClient();
var html = await client.GetStringAsync(url);
});
Run Code Online (Sandbox Code Playgroud)
这是问题所在,它会同时启动1000多个Web请求.有没有一种简单的方法来限制这些异步http请求的并发数量?这样在任何给定时间都不会下载超过20个网页.如何以最有效的方式做到这一点?
我处理的项目是Web服务器上托管的Web应用程序调用托管在应用服务器上的WCF服务.WCF调用的代理由ChannelFactory创建,调用通过channel进行,例如:
(省略使用块)
var factory = new ChannelFactory<IUserService>(endpointConfigurationName);
var channel = factory.CreateChannel();
var users = channel.GetAllUsers();
Run Code Online (Sandbox Code Playgroud)
如果我理解的话,通过频道调用是异步的,Web服务器上的线程在请求期间是空闲的,只是等待响应.
我想像这样打电话异步:
var users = await channel.GetAllUsersAsync();
Run Code Online (Sandbox Code Playgroud)
有没有办法如何使用ChannelFactory和通道异步进行调用?我没找到任何.我知道我可以通过svcutil/Add服务引用生成异步方法,但我不想那样做.另外,我不想通过添加异步方法来更改应用服务器(IUserService)上的服务接口.
有没有办法如何使用ChannelFactory调用方法异步?谢谢.
我正在使用WCF和TPL异步库,我需要的是能够请求多个WCF方法并等待所有步骤都完成,到目前为止,我发现.NET 4.5中有非常方便的方法Task.Factory.ContinueWhenAll可以用于等待所有通话结束
我发现了以下几种以异步方式请求WCF调用的方法
。通过使用由“添加引用”对话框生成的代理以及选项“生成基于任务的操作”-> [例如,此处] [1]-在我的情况下不是一个选项就像我们使用Raw ChannelFactory
Option 2一样。通过将同步调用包装在任务中,例如
ChannelFactory<IService1> factory = new ChannelFactory<IService1>("BasicHttpBinding_IService1");
Task<string> t1 = Task<string>.Factory.StartNew(() => { return factory.CreateChannel().GetData(2); });
Task<string> t2 = Task<string>.Factory.StartNew(() => { return factory.CreateChannel().GetData(5); });
Task.Factory.ContinueWhenAll(new[] { t1, t2 }, t =>
{
foreach (var task in t)
{
//get result here
}
});
Run Code Online (Sandbox Code Playgroud)
选项3.通过创建客户端异步版本的契约接口,例如
[ServiceContract(Namespace = "X", Name = "TheContract")]//Server side contract
public interface IService1
{
[OperationContract]
string GetData(int value);
}
[ServiceContract(Namespace = "X", Name = "TheContract")]//client side contract
public …Run Code Online (Sandbox Code Playgroud)