我有一个public async void Foo()
方法,我想从同步方法调用.到目前为止,我从MSDN文档中看到的是通过异步方法调用异步方法,但我的整个程序不是使用异步方法构建的.
这甚至可能吗?
以下是从异步方法调用这些方法的一个示例:http://msdn.microsoft.com/en-us/library/hh300224(v = vs.110).aspx
现在我正在研究从同步方法调用这些异步方法.
我有方法:
private static void Method()
{
Console.WriteLine("Method() started");
for (var i = 0; i < 20; i++)
{
Console.WriteLine("Method() Counter = " + i);
Thread.Sleep(500);
}
Console.WriteLine("Method() finished");
}
Run Code Online (Sandbox Code Playgroud)
我想在一个新的Task中启动这个方法.我可以开始这样的新任务
var task = Task.Factory.StartNew(new Action(Method));
Run Code Online (Sandbox Code Playgroud)
或这个
var task = Task.Run(new Action(Method));
Run Code Online (Sandbox Code Playgroud)
但是Task.Run()
和之间有什么区别吗Task.Factory.StartNew()
?它们都使用ThreadPool并在创建Task的实例后立即启动Method().当我们应该使用第一个变体和第二个?
我有以下场景,我认为这可能很常见:
有一个任务(一个UI命令处理程序)可以同步或异步完成.
命令的到达速度可能比处理它们的速度快.
如果命令已有待处理任务,则应对新命令处理程序任务进行排队并按顺序处理.
每个新任务的结果可能取决于前一个任务的结果.
应该遵守取消,但为了简单起见,我想将其排除在本问题的范围之外.此外,线程安全(并发)不是必需的,但必须支持重入.
这是我想要实现的基本示例(作为控制台应用程序,为简单起见):
using System;
using System.Threading.Tasks;
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
var asyncOp = new AsyncOp<int>();
Func<int, Task<int>> handleAsync = async (arg) =>
{
Console.WriteLine("this task arg: " + arg);
//await Task.Delay(arg); // make it async
return await Task.FromResult(arg); // sync
};
Console.WriteLine("Test #1...");
asyncOp.RunAsync(() => handleAsync(1000));
asyncOp.RunAsync(() => handleAsync(900));
asyncOp.RunAsync(() => handleAsync(800));
asyncOp.CurrentTask.Wait();
Console.WriteLine("\nPress any key to continue to test #2...");
Console.ReadLine();
asyncOp.RunAsync(() =>
{
asyncOp.RunAsync(() => handleAsync(200)); …
Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个WebApi方法,该方法运行一系列难以进一步优化的循环计算.
x.Items.AsParallel().ForAll(item =>
{
item.RunCalcs();
});
Run Code Online (Sandbox Code Playgroud)
当执行此代码时,通过查看服务器任务管理器,它似乎只会最大化单个处理器核心,同时保持其他核心不受影响.
根据我的阅读,asp.net将单个请求限制为一个处理器核心.由于这是一个总体请求很少的Intranet服务器,因此我不关心管理服务器资源.
有没有办法覆盖或解决这种行为,使我的循环运行得更快?
我知道之前已经问过这个问题,但谷歌搜索后我得不到正确的答案.
我有这些代码行:
Task.Run(() => DoSomething())
.ContinueWith(t=>Log.Error(t,"Error"), TaskContinuationOptions.OnlyOnFaulted);
Task.Factory.StartNew(() => DoSomething())
.ContinueWith(t=>Log.Error(t,"Error"),TaskContinuationOptions.OnlyOnFaulted);
Run Code Online (Sandbox Code Playgroud)
成功运行后DoSomething
,Task.Run
投掷TaskCanceledException
时Task.Factory.StartNew
工作正常.为什么?
进一步阅读:
Stephen Clearly为什么不使用Task.Factory.StartNew
MSDN Link
更新2: 示例代码:
private async void button27_Click(object sender, EventArgs e)
{
var r = new Random(System.DateTime.Now.Millisecond);
await Task.Factory.StartNew(
() => {
Divide(r.Next(100), r.Next(-1, 10));
Log.Information("Divide Done!");
},
CancellationToken.None,
TaskCreationOptions.DenyChildAttach,
TaskScheduler.Default)
.ContinueWith(
t => {
Log.Error(t.Exception,"There is an exception on Divide");
},
TaskContinuationOptions.OnlyOnFaulted);
}
private static void Divide(int a, int b)
{
var c = a/b;
}
Run Code Online (Sandbox Code Playgroud) 假设我有一个定义如下的方法:
public async Task CreateUser()
{
await GetUserDetails();
GetUserOrder();
}
private void GetUserDetails() {
private void GetUserOrder() {
Run Code Online (Sandbox Code Playgroud)
请问方法GetUserDetails();
和GetUserOrder()
必须async
,以及避免UI拦截?
我不能await
这个GetUserDetails()
方法因为它不是异步的.我怎样才能在c#中实现这一目标?我想确保一步一步调用所有这些方法.