我有一个Silverlight项目,我试图在构造函数中填充一些数据:
public class ViewModel
{
public ObservableCollection<TData> Data { get; set; }
async public ViewModel()
{
Data = await GetDataTask();
}
public Task<ObservableCollection<TData>> GetDataTask()
{
Task<ObservableCollection<TData>> task;
//Create a task which represents getting the data
return task;
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,我收到一个错误:
修饰符
async对此项目无效
当然,如果我在标准方法中包装并从构造函数中调用它:
public async void Foo()
{
Data = await GetDataTask();
}
Run Code Online (Sandbox Code Playgroud)
它工作正常.同样,如果我使用旧的由内而外的方式
GetData().ContinueWith(t => Data = t.Result);
Run Code Online (Sandbox Code Playgroud)
这也有效.我只是想知道为什么我们不能await直接在构造函数内调用.可能有很多(甚至是明显的)边缘情况和反对它的理由,我只是想不出来.我也在寻找解释,但似乎找不到任何解释.
使用Parallel.ForEach或Task.Run()以异步方式启动一组任务有什么区别?
版本1:
List<string> strings = new List<string> { "s1", "s2", "s3" };
Parallel.ForEach(strings, s =>
{
DoSomething(s);
});
Run Code Online (Sandbox Code Playgroud)
版本2:
List<string> strings = new List<string> { "s1", "s2", "s3" };
List<Task> Tasks = new List<Task>();
foreach (var s in strings)
{
Tasks.Add(Task.Run(() => DoSomething(s)));
}
await Task.WhenAll(Tasks);
Run Code Online (Sandbox Code Playgroud) 我怎么能等待void async方法完成它的工作?
例如,我有一个如下功能:
async void LoadBlahBlah()
{
await blah();
...
}
Run Code Online (Sandbox Code Playgroud)
现在我想确保在继续其他地方之前已经加载了所有内容.
在查看各种C#异步CTP示例时,我看到一些返回的异步函数void,以及其他返回非泛型函数的异步函数Task.我可以看到为什么返回a Task<MyType>对于在异步操作完成时将数据返回给调用者很有用,但是我看到的返回类型的函数Task永远不会返回任何数据.为什么不回来void?
我有一个看起来像这样的方法:
private async void DoStuff(long idToLookUp)
{
IOrder order = await orderService.LookUpIdAsync(idToLookUp);
// Close the search
IsSearchShowing = false;
}
//Other stuff in case you want to see it
public DelegateCommand<long> DoLookupCommand{ get; set; }
ViewModel()
{
DoLookupCommand= new DelegateCommand<long>(DoStuff);
}
Run Code Online (Sandbox Code Playgroud)
我试图对它进行单元测试:
[TestMethod]
public void TestDoStuff()
{
//+ Arrange
myViewModel.IsSearchShowing = true;
// container is my Unity container and it setup in the init method.
container.Resolve<IOrderService>().Returns(orderService);
orderService = Substitute.For<IOrderService>();
orderService.LookUpIdAsync(Arg.Any<long>())
.Returns(new Task<IOrder>(() => null));
//+ Act
myViewModel.DoLookupCommand.Execute(0);
//+ Assert
myViewModel.IsSearchShowing.Should().BeFalse(); …Run Code Online (Sandbox Code Playgroud) 我有一个非常简单的ASP.NET MVC 4控制器:
public class HomeController : Controller
{
private const string MY_URL = "http://smthing";
private readonly Task<string> task;
public HomeController() { task = DownloadAsync(); }
public ActionResult Index() { return View(); }
private async Task<string> DownloadAsync()
{
using (WebClient myWebClient = new WebClient())
return await myWebClient.DownloadStringTaskAsync(MY_URL)
.ConfigureAwait(false);
}
}
Run Code Online (Sandbox Code Playgroud)
当我启动项目时,我看到了我的视图,它看起来很好,但是当我更新页面时,我收到以下错误:
[InvalidOperationException:在异步操作仍处于挂起状态时完成异步模块或处理程序.
为什么会这样?我做了几个测试:
task = DownloadAsync();从构造函数中删除并将其放入Index方法中它将正常工作而没有错误.DownloadAsync()身体return await Task.Factory.StartNew(() => { Thread.Sleep(3000); return "Give me an error"; });它将正常工作.为什么不可能WebClient.DownloadStringTaskAsync在控制器的构造函数中使用该方法?
我有异步回调,它被传递到Timer(来自System.Threading)构造函数:
private async Task HandleTimerCallback(object state)
{
if (timer == null) return;
if (asynTaskCallback != null)
{
await HandleAsyncTaskTimerCallback(state);
}
else
{
HandleSyncTimerCallback(state);
}
}
Run Code Online (Sandbox Code Playgroud)
和计时器:
timer = new Timer(async o => await HandleTimerCallback(o), state, CommonConstants.InfiniteTimespan,
CommonConstants.InfiniteTimespan);
Run Code Online (Sandbox Code Playgroud)
有没有办法o在lambda中省略那个参数?非同步的原因我可以将我handler作为委托传递
timer = new Timer(HandleTimerCallback, state, CommonConstants.InfiniteTimespan,
CommonConstants.InfiniteTimespan);
Run Code Online (Sandbox Code Playgroud) 所以,我有这个Web API动作,它执行一个异步函数.
public void Post([FromBody]InsertRequest request)
{
InsertPostCommand.Execute(request);
DoAsync();
}
private async void DoAsync()
{
await Task.Run(() =>
{
//do async stuff here
});
}
Run Code Online (Sandbox Code Playgroud)
我实际上希望控制器操作在执行异步操作时返回到客户端.
我这样做了,因此我得到一个例外:
System.InvalidOperationException: An asynchronous module or handler completed while an asynchronous operation was still pending.
Run Code Online (Sandbox Code Playgroud)
我怎么能实现这个呢?
谢谢
c# ×8
async-await ×5
asynchronous ×4
.net ×2
asp.net ×1
async-ctp ×1
constructor ×1
lambda ×1
return-type ×1
timer ×1
unit-testing ×1
webclient ×1