当我有两个任务并等待一个任务时,我无法理解控制流程.异步程序(C#和Visual Basic)中的控制流只使用一个等待,所以它没有帮助.
我有以下代码:
public async Task Loop(string name, int count)
{
for (int i = 0; i < count; i++)
{
Console.WriteLine("{0}: {1} Before", name, i);
await Task.Delay(10);
Console.WriteLine("{0}: {1} After", name, i);
}
Console.WriteLine("{0} COMPLETE", name);
}
[TestMethod]
public async Task TwoLoopsWithSeparateAwait()
{
var loopOne = Loop("ONE", 3);
Console.WriteLine("After ONE Creation");
var loopTwo = Loop("TWO", 3);
Console.WriteLine("After TWO Creation, before ONE await");
await loopOne;
Console.WriteLine("After ONE await");
await loopTwo;
Console.WriteLine("After TWO await");
}
Run Code Online (Sandbox Code Playgroud)
结果如下:
为什么可以在C#中执行此操作?
var task = Task.Run (...);
await task;
Run Code Online (Sandbox Code Playgroud)
是不是Task.Run()应该用于CPU绑定代码?要求await这个有意义吗?
即,在调用后Task.Run我明白该任务正在线程池的另一个线程中运行.打电话的目的是await什么?打电话不会更有意义task.Wait()吗?
最后一个问题,我的第一印象await是打算专门用于async方法.将它用于返回的任务是否常见Task.Run()?
编辑.这也让我想知道,为什么我们有Task.Wait ()而不是Task.Await().我的意思是,为什么一个方法被用于Wait()和一个keyworkd await.在两种情况下使用方法都不会更一致吗?
我目前正在构建现有API的异步启用版本,并且我很难找到关于何时支持取消的好主意的任何指导.在BCL一些异步方法不具有接受过载CancellationToken,我发现这个MSDN文章该条规定
并非所有异步方法都支持取消
那么,有什么条件可以通过一个支持取消CancellationToken?
我倾向于以下条件:
那些合理的条件吗?还有其他人吗?
我正在实现一些异步工作并且无法帮助,但我觉得我最终会得到一个非常难看的构造,我想知道是否以及如何将其重写为"感觉更好"的东西.
var tasks = new List<Task>();
var t1 = new Task<Guid>(() => DoSomeStuff<Xyz>(dtx, e1, M1));
var t2 = new Task<Guid>(() => DoSomeStuff<Qrs>(dtx, e2, M2));
var t3 = new Task<Guid>(() => DoSomeStuff<Abc>(dtx, e3, M3));
tasks.Add(t1);
tasks.Add(t2);
tasks.Add(t3);
tasks.ForEach(x => x.Start());
Task.WaitAll(tasks.ToArray<Task>());
returnDto.t1value = t1.Result;
returnDto.t2value = t2.Result;
returnDto.t3value = t3.Result;
Run Code Online (Sandbox Code Playgroud)
为简洁起见,变量名称已被更改,实际上还有更多任务.任务都可以独立运行,但所有任务都必须在我们继续之前完成.
DoSomeStuff 看起来像这样:
private Guid DoSomeStuff<T>(DependentTransaction dtx, T thing, Func<T, Guid> method)
Run Code Online (Sandbox Code Playgroud) 我已经将同一段代码从一个项目复制到另一个项目,在第一个项目中它编译得很好,但在第二个项目中它没有.
这件作品是:
using Windows.Devices.Bluetooth;
// a couple of lines of other code
var rfcommProvider = await RfcommServiceProvider.CreateAsync(RfcommServiceId.FromUuid(RfcommChatServiceUuid));
Run Code Online (Sandbox Code Playgroud)
错误:
'await' requires that the type 'Windows.Foundation.IAsyncOperation<Windows.Devices.Bluetooth.Rfcomm.RfcommServiceProvider>' have a suitable GetAwaiter method. Are you missing a using directive for 'System'?
Run Code Online (Sandbox Code Playgroud)
第一个项目是由Microsoft创建的演示,它是一个Windows 8.1应用程序.
我的应用程序是正常的WPF应用程序,它的目标是.NET 4.5.1和Windows 8.1和我加了参考Windows.winmd描述这里
我不知道为什么同一段代码可能在一个应用程序中编译而在另一个应用程序中编译时,如引用,命名空间等所有常见的东西都可以.我唯一的想法是,我可能正在引用一些尚未等待的旧版本,但我不知道如何验证这一点.
在ASP.NET Web API项目中,我有一个动作过滤器,用于检查模型状态错误并返回Bad Request状态代码(如果有).它看起来像这样:
public class ValidationFilter : IActionFilter
{
public Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext context,
CancellationToken cancellationToken,
Func<Task<HttpResponseMessage>> continuation)
{
if(!actionContext.ModelState.IsValid)
{
return new Task<HttpResponseMessage>(() =>
actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest,
actionContext.ModelState);
}
return continuation();
}
}
Run Code Online (Sandbox Code Playgroud)
现在,出于某种原因,任何具有模型状态错误的请求都不会返回.它只是挂在那里.如果我调试,我会进入管道中的下一个过滤器,它开始于
var result = await continuation();
Run Code Online (Sandbox Code Playgroud)
如果我"跳过"该行,则调试器会退出"等待"模式,但似乎不再运行代码.
我认为所有这一切都是因为我在某种程度上误解了所有这些事情是如何相互作用的,但是尽管谷歌搜索和阅读了几个小时,我仍然无法弄清楚如何使这项工作正常.任何帮助 - 无论是理解还是错误修正 - 都深受赞赏.
在旧的API(1.X)中,您可以通过使用从以下位置返回State的MongoServer实例上的属性来判断服务器是否已连接MongoClient.GetServer:
public bool IsConnceted
{
get
{
return _client.GetServer().State == MongoServerState.Connected;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,GetServer它不是新API(2.0)的一部分.怎么能实现呢?
我有一个在初始化组件之后调用的方法,方法签名如下:
public async void method_name ()
{
// code ...
}
Run Code Online (Sandbox Code Playgroud)
在该方法中,我有一个循环运行4个不同的if语句.我需要循环暂停每个if语句并等待用户按下按钮.由于按下该按钮将添加信息和内容.按下按钮后,我希望循环继续,当然会在下一个if语句处暂停.
我想这样做await Task.Delay(30000);但是如果用户在定时器结束之前完成输入信息,他/她就会等待.而那效率不高.
在Jon Skeet的C#6帖子中,他用C#6命名了Clean Event Handlers Invocation,他展示了你现在如何写作
public void OnFoo()
{
Foo?.Invoke(this, EventArgs.Empty);
}
Run Code Online (Sandbox Code Playgroud)
代替
public void OnFoo()
{
EventHandler handler = Foo;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
Run Code Online (Sandbox Code Playgroud)
如果我们谈论一个等待的方法,有没有办法做这样的单线程?如果我试试
await Foo?.Invoke();
Run Code Online (Sandbox Code Playgroud)
我得到以下编译错误:
所述awaiter类型
System.Runtime.CompilerServices.TaskAwaiter?必须有合适的IsCompleted和GetResult构件(CS4011).
注意:我使用的是Mono(Xamarin Studio for OSX v5.9.5),因此编译器结果可能与使用Visual Studio的结果不同.
简而言之,我有这样的事情:
class MyClass
{
double SomeProperty {get; private set;}
public async Task SomeMethod()
{
SomeProperty = await someService.SomeAsyncMethod();
}
}
Run Code Online (Sandbox Code Playgroud)
SomeProperty如果我SomeMethod()同时多次打电话可能会被破坏?
c# ×10
.net ×8
async-await ×8
asynchronous ×1
bluetooth ×1
c#-6.0 ×1
cancellation ×1
concurrency ×1
loops ×1
mongodb ×1
mono ×1
task ×1