我有一个public async void Foo()方法,我想从同步方法调用.到目前为止,我从MSDN文档中看到的是通过异步方法调用异步方法,但我的整个程序不是使用异步方法构建的.
这甚至可能吗?
以下是从异步方法调用这些方法的一个示例:http://msdn.microsoft.com/en-us/library/hh300224(v = vs.110).aspx
现在我正在研究从同步方法调用这些异步方法.
我有一个async方法:
public async Task<string> GenerateCodeAsync()
{
string code = await GenerateCodeService.GenerateCodeAsync();
return code;
}
Run Code Online (Sandbox Code Playgroud)
我需要从同步方法中调用此方法.
如何在不必复制GenerateCodeAsync方法的情况下执行此操作以使其同步工作?
更新
然而找不到合理的解决方案
但是,我看到HttpClient已经实现了这种模式
using (HttpClient client = new HttpClient())
{
// async
HttpResponseMessage responseAsync = await client.GetAsync(url);
// sync
HttpResponseMessage responseSync = client.GetAsync(url).Result;
}
Run Code Online (Sandbox Code Playgroud) 我正在构建一个类API来与API进行交互.我需要调用API并处理XML响应.我可以看到HttpClient用于异步连接的好处,但我正在做的是纯粹的同步,所以我看不到使用它的任何重大好处HttpWebRequest.
如果有人可以放弃任何光线,我将非常感激.我不是为了它而使用新技术的人.
我怎么能等待void async方法完成它的工作?
例如,我有一个如下功能:
async void LoadBlahBlah()
{
await blah();
...
}
Run Code Online (Sandbox Code Playgroud)
现在我想确保在继续其他地方之前已经加载了所有内容.
我有以下四个测试,当我运行它时,最后一个测试挂起,我的问题是为什么会发生这种情况:
[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) 什么是使用模式HttpResponseMessage.EnsureSuccessStatusCode()?它处理消息的内容并抛出HttpRequestException,但是我没有看到如何以编程方式处理它而不是通用的Exception.例如,它不包括HttpStatusCode,这将是方便的.
有没有办法从中获取更多信息?任何人都可以显示两者的相关使用模式EnsureSuccessStatusCode()和HttpRequestException吗?
我正在更新具有在.NET 3.5中构建的API表面的库.因此,所有方法都是同步的.我无法更改API(即,将返回值转换为Task),因为这将要求所有调用者都更改.所以我留下了如何以同步方式最好地调用异步方法.这是在ASP.NET 4,ASP.NET Core和.NET/.NET Core控制台应用程序的上下文中.
我可能不够清楚 - 情况是我现有的代码不是异步识别的,我想使用新的库,如System.Net.Http和仅支持异步方法的AWS SDK.所以我需要缩小差距,并且能够拥有可以同步调用的代码,然后可以在其他地方调用异步方法.
我已经做了很多阅读,并且有很多次这已经被问及并回答了.
问题是大多数答案都不同!我见过的最常见的方法是使用.Result,但这可能会死锁.我已经尝试了以下所有内容,并且它们可以工作,但我不确定哪种方法可以避免死锁,具有良好的性能,并且可以很好地运行运行时(在尊重任务调度程序,任务创建选项等方面) ).有明确的答案吗?什么是最好的方法?
private static T taskSyncRunner<T>(Func<Task<T>> task)
{
T result;
// approach 1
result = Task.Run(async () => await task()).ConfigureAwait(false).GetAwaiter().GetResult();
// approach 2
result = Task.Run(task).ConfigureAwait(false).GetAwaiter().GetResult();
// approach 3
result = task().ConfigureAwait(false).GetAwaiter().GetResult();
// approach 4
result = Task.Run(task).Result;
// approach 5
result = Task.Run(task).GetAwaiter().GetResult();
// approach 6
var t = task();
t.RunSynchronously();
result = t.Result;
// approach 7
var t1 = task();
Task.WaitAll(t1); …Run Code Online (Sandbox Code Playgroud) c# asp.net multithreading asynchronous task-parallel-library
是否可以强制任务在当前线程上同步执行?
也就是说,通过例如传递一些参数StartNew()来制作这段代码是否可能:
Task.Factory.StartNew(() => ThisShouldBeExecutedSynchronously());
Run Code Online (Sandbox Code Playgroud)
表现得像这样:
ThisShouldBeExecutedSynchronously();
Run Code Online (Sandbox Code Playgroud)
背景:
我有一个名为的界面IThreads:
public interface IThreads
{
Task<TRet> StartNew<TRet>(Func<TRet> func);
}
Run Code Online (Sandbox Code Playgroud)
我想有两个这样的实现,一个使用线程的普通:
public class Threads : IThreads
{
public Task<TRet> StartNew<TRet>(Func<TRet> func)
{
return Task.Factory.StartNew(func);
}
}
Run Code Online (Sandbox Code Playgroud)
并且不使用线程(在某些测试场景中使用):
public class NoThreading : IThreads
{
public Task<TRet> StartNew<TRet>(Func<TRet> func)
{
// What do I write here?
}
}
Run Code Online (Sandbox Code Playgroud)
我可以让NoThreading版本调用func(),但我想返回一个Task<TRet>我可以执行操作的实例,例如ContinueWith().
我正在评估Async CTP.
如何在另一个线程池的线程上开始执行异步函数?
static async Task Test()
{
// Do something, await something
}
static void Main( string[] args )
{
// Is there more elegant way to write the line below?
var t = TaskEx.Run( () => Test().Wait() );
// Doing much more in this same thread
t.Wait(); // Waiting for much more then just this single task, this is just an example
}
Run Code Online (Sandbox Code Playgroud) 我需要调用一个Task从内部返回a的方法
public override void OnActionExecuting(ActionExecutingContext filterContext)
Run Code Online (Sandbox Code Playgroud)
它不会让我使这个方法异步它抛出以下
在异步操作仍处于挂起状态时完成异步模块或处理程序.
并在打电话时
entityStorage.GetCurrentUser().Result
Run Code Online (Sandbox Code Playgroud)
我陷入僵局.我怎么能避免这个?
我一直在玩它想出类似的东西
entityStorage.GetCurrentUser().Result.ConfigureAwait(false).GetAwaiter().GetResult();
Run Code Online (Sandbox Code Playgroud)
但这不起作用.我该怎么做?我的解决方案需要使用ASP.NET 4和Async Targetting Pack,我不能使用ASP.NET 4.5作为部署到Azure.
c# ×8
asp.net ×4
async-await ×4
asynchronous ×3
.net ×2
asp.net-4.0 ×1
asp.net-mvc ×1
async-ctp ×1
c#-4.0 ×1
deadlock ×1
httprequest ×1
nunit ×1
system.net ×1
task ×1