我有一个public async void Foo()方法,我想从同步方法调用.到目前为止,我从MSDN文档中看到的是通过异步方法调用异步方法,但我的整个程序不是使用异步方法构建的.
这甚至可能吗?
以下是从异步方法调用这些方法的一个示例:http://msdn.microsoft.com/en-us/library/hh300224(v = vs.110).aspx
现在我正在研究从同步方法调用这些异步方法.
我有以下四个测试,当我运行它时,最后一个测试挂起,我的问题是为什么会发生这种情况:
[Test]
public void CheckOnceResultTest()
{
Assert.IsTrue(CheckStatus().Result);
}
[Test]
public async void CheckOnceAwaitTest()
{
Assert.IsTrue(await CheckStatus());
}
[Test]
public async void CheckStatusTwiceAwaitTest()
{
Assert.IsTrue(await CheckStatus());
Assert.IsTrue(await CheckStatus());
}
[Test]
public async void CheckStatusTwiceResultTest()
{
Assert.IsTrue(CheckStatus().Result); // This hangs
Assert.IsTrue(await CheckStatus());
}
private async Task<bool> CheckStatus()
{
var restClient = new RestClient(@"https://api.test.nordnet.se/next/1");
Task<IRestResponse<DummyServiceStatus>> restResponse = restClient.ExecuteTaskAsync<DummyServiceStatus>(new RestRequest(Method.GET));
IRestResponse<DummyServiceStatus> response = await restResponse;
return response.Data.SystemRunning;
}
Run Code Online (Sandbox Code Playgroud)
我将此扩展方法用于restsharp RestClient:
public static class RestClientExt
{
public static Task<IRestResponse<T>> ExecuteTaskAsync<T>(this RestClient client, IRestRequest …Run Code Online (Sandbox Code Playgroud) 在某些时候,CoreCLR支持异步主入口点.见http://blog.stephencleary.com/2015/03/async-console-apps-on-net-coreclr.html
但是,以下程序在.NET Core RTM中都不起作用
using System;
using System.Threading.Tasks;
namespace ConsoleApplication
{
public class Program
{
public static async Task Main(string[] args)
{
await Task.Delay(1000);
Console.WriteLine("Hello World!");
}
}
}
Run Code Online (Sandbox Code Playgroud)
要么
using System;
using System.Threading.Tasks;
namespace ConsoleApplication
{
public class Program
{
public async Task Main(string[] args)
{
await Task.Delay(1000);
Console.WriteLine("Hello World!");
}
}
}
Run Code Online (Sandbox Code Playgroud)
这两个都失败了,错误:
错误CS5001:程序不包含适用于入口点的静态"主"方法
.NET Core RTM是否支持异步控制台应用程序?
我按照Microsoft的Hello Key Vault示例应用程序中的示例在我的ASP.Net MVC Web应用程序上设置了Azure Keyvault .
Azure KeyVault(Active Directory)AuthenticationResult默认情况下有一个小时到期.因此,一小时后,您必须获得一个新的身份验证令牌.在获得我的第一个AuthenticationResult令牌后,KeyVault正在按预期工作,但在1小时到期后,它无法获得新令牌.
不幸的是,我的生产环境失败让我意识到这一点,因为我从未测试过去一小时的开发.
无论如何,经过两天多的努力弄清楚我的keyvault代码出了什么问题,我提出了一个解决方案来修复我的所有问题 - 删除异步代码 - 但感觉非常hacky.我想找出为什么它首先不起作用.
我的代码看起来像这样:
public AzureEncryptionProvider() //class constructor
{
_keyVaultClient = new KeyVaultClient(GetAccessToken);
_keyBundle = _keyVaultClient
.GetKeyAsync(_keyVaultUrl, _keyVaultEncryptionKeyName)
.GetAwaiter().GetResult();
}
private static readonly string _keyVaultAuthClientId =
ConfigurationManager.AppSettings["KeyVaultAuthClientId"];
private static readonly string _keyVaultAuthClientSecret =
ConfigurationManager.AppSettings["KeyVaultAuthClientSecret"];
private static readonly string _keyVaultEncryptionKeyName =
ConfigurationManager.AppSettings["KeyVaultEncryptionKeyName"];
private static readonly string _keyVaultUrl =
ConfigurationManager.AppSettings["KeyVaultUrl"];
private readonly KeyBundle _keyBundle;
private readonly KeyVaultClient _keyVaultClient;
private static async Task<string> GetAccessToken(
string authority, string resource, …Run Code Online (Sandbox Code Playgroud) 如何避免为异步和非异步方法编写相同的代码两次.我目前正在使用ASP.NET,因此我目前正在使用请求线程,并且我很快就知道他在代码下面(应该显示我的意图),这肯定是错误的做法.
应用程序死锁,因为await关键字试图返回.Result阻塞的同一线程.
我这样做的全部原因是避免两次编写相同的"FindAll"代码.
public IEnumerable<Resource> FindAll()
{
return FindAllAsync().Result;
}
public async Task<IEnumerable<Resource>> FindAllAsync()
{
return await Context.Resources.ToListAsync();
}
Run Code Online (Sandbox Code Playgroud)
那你怎么解决这个问题呢?
我只是想知道方法是什么?在什么样的场景中我可以使用这种方法.
我最初的想法是RunSynchronously调用异步方法并同步运行它而不会造成死锁问题.wait().
但是,根据MSDN,
通常,任务在线程池线程上异步执行,不会阻塞调用线程.通过调用RunSynchronously()方法执行的任务与当前的TaskScheduler相关联,并在调用线程上运行.如果目标调度程序不支持在调用线程上运行此任务,则将调度任务以在调度上执行,并且调用线程将阻塞,直到任务完成执行
为什么在这里需要一个TaskScheduler,如果任务将在调用线程上运行?
我有一个与SignalR Hub(服务器)通信的.Net Windows服务(客户端).大多数客户端方法需要时间才能完成.当从服务器接收调用时,我如何(或者我需要)包装目标方法/ hub.On以避免警告:
"因为没有等待这个调用,所以当前方法的执行在调用完成之前继续.考虑将await运算符应用于调用的结果"
在客户端上,这是启动/设置代码的示例:
IHubProxy _hub
string hubUrl = @"http://localhost/";
var connection = new HubConnection(hubUrl, hubParams);
_hub = connection.CreateHubProxy("MyHub");
await connection.Start();
_hub.On<Message>("SendMessageToClient", i => OnMessageFromServer(i.Id, i.Message));
_hub.On<Command>("SendCommandToClient", i => OnCommandFromServer(i.Id, i.Command));
Run Code Online (Sandbox Code Playgroud)
同样在客户端上,这是方法的示例:
public static async Task<bool> OnMessageFromServer(string Id, string message)
{
try
{
var result = await processMessage(message); //long running task
}
catch (Exception ex)
{
throw new Exception("There was an error processing the message: ", ex);
}
return result;
}
public static async Task<bool> OnCommandFromServer(string Id, string …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) 用于Signalr的.NET核心客户端具有HubConnection可按以下方式使用的类。
HubConnection connection = new HubConnectionBuilder()
.WithUrl("https://localhost:44321/hub")
.Build();
await connection.StartAsync();
connection.On<SomeEvent>("HubMethodName", (ev) => Console.WriteLine("EventHandler"))
Run Code Online (Sandbox Code Playgroud)
我想在事件处理程序中进行一些异步工作,但是对我来说,如何立即执行并不太明显,因为大多数重载都期望an Action。使用async void作品,但我不确定这是一个好主意。另外,签名有一个过载,On(string methodName, Type[] parameters, Func<object[], Task>) handler)这是有希望的,但是我想我会期望带有的过载On<T>(string methodName, Func<T, Task> handler)。我可以自己创建带有该签名的扩展方法,但是当它不存在时,我想我可能已经错过了一些重要的事情吗?
我正在调用一个返回任务的方法,在调用方法中我需要以字符串的形式读取响应。
这是我放置的代码:
static public async Task<HttpResponseMessage> Validate(string baseUri,HttpContent content) {
HttpResponseMessage response = new HttpResponseMessage();
response = await client.PostAsync(baseUri,content);
return response;
}
public string test(){
string postJson = "{Login = \"user\", Password = \"pwd\"}";
HttpContent stringContent = new StringContent(postJson,
UnicodeEncoding.UTF8, "application/json");
HttpResponseMessage result=Validate(Uri,stringContent);
var json = result.Content.ReadAsStringAsync().Result;
}
Run Code Online (Sandbox Code Playgroud)
我期望字符串,但会引发此错误:
Cannot implicitly convert type
'System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage>' to
'System.Net.Http.HttpResponseMessage'
Run Code Online (Sandbox Code Playgroud) c# ×9
async-await ×5
.net ×3
.net-core ×1
asp.net ×1
asp.net-mvc ×1
asynchronous ×1
azure ×1
deadlock ×1
nunit ×1
task ×1