根据这篇文章,我们不应该提供异步实现的同步包装器.
我们已经抽象了System.Net.SmtpClient一个接口,以便我们可以轻松测试发送电子邮件的代码.
由于SmtpClient实际上同时具有异步和同步实现,我们是否应该公开这两个实现,或者只是希望我们的ISmtpClient接口的任何使用者只是Wait我们的异步SendAsync方法.
在构建通用库时,不确定这里的准则是什么.在我们的例子中,我们知道我们需要同时使用异步和同步版本.
我正在尝试使用服务引用,使用任务调度程序同时发出多个请求.该服务包括一个返回结果集的同步和异步函数.我有点困惑,我有几个初步的问题,然后我将分享我在每个问题中取得的进展.我正在使用一些日志记录,并发可视化器和提琴手进行调查.最终,我想使用反应式调度程序来尽可能多地发出请求.
1)我应该使用异步函数来发出所有请求吗?
2)如果我在多个任务中使用同步函数,那么可能会使我的线程计数匮乏的有限资源是什么?
这是我到目前为止:
var myScheduler = new myScheduler();
var myFactory = new Factory(myScheduler);
var myClientProxy = new ClientProxy();
var tasks = new List<Task<Response>>();
foreach( var request in Requests )
{
var localrequest = request;
tasks.Add( myFactory.StartNew( () =>
{
// log stuff
return client.GetResponsesAsync( localTransaction.Request );
// log some more stuff
}).Unwrap() );
}
Task.WaitAll( tasks.ToArray() );
// process all the requests after they are done
Run Code Online (Sandbox Code Playgroud)
这会运行,但根据fiddler,它只是尝试立即执行所有请求.它可能是调度程序,但我相信我做的更多.
我也尝试在没有unwrap命令的情况下实现它,而是使用异步await委托,它也做同样的事情.我也试过引用.result,这似乎顺序完成.使用与调度程序/工厂的非同步服务函数调用,每个客户端同时只能同时获得大约20个并发请求.
Action直接指定或Func<Task>使用.NET TPL Dataflow有ActionBlock什么区别?
直接行动:
new ActionBlock<Message[]>(x => DoSomething(x))
Run Code Online (Sandbox Code Playgroud)
任务:
new ActionBlock<Message[]>(x => Task.Run(() => DoSomething(x)))
Run Code Online (Sandbox Code Playgroud)
我试图了解并行执行方面的差异(MaxDegreeOfParallelism> 1).
我尝试了async/await的一些东西,但我真的没有得到它.我想要开始的所有内容是同时从两个不同的线程写入控制台.这是代码:
static void Main(string[] args)
{
DoSomethingAsync();
for (int i = 0; i < 1000; i++)
Console.Write(".");
Console.ReadLine();
}
static async void DoSomethingAsync()
{
Console.WriteLine("DoSomethingAsync enter");
//This does not seem good
await Task.Delay(1);
for (int i = 0; i < 1000; i++)
Console.Write("X");
Console.WriteLine("DoSomethingAsync exit");
}
Run Code Online (Sandbox Code Playgroud)
使用Threads很容易但是使用async/await我只能在完成这个奇怪的操作时完成它
await Task.Delay(1);
Run Code Online (Sandbox Code Playgroud)
我看到的大多数基本例子都使用过它 但是,当你想做一些不同步的时间时,该怎么做?你不能等待任何东西,因此所有代码都在主线程上运行.如何在不使用Task.Delay()的情况下实现与此代码相同的行为?
我试图通过局部变量获得线程结果.
有代码:
static void Main()
{
long res1 = 0, res2 = 0;
long n1 = 5000, n2 = 10000;
Thread t1 = new Thread(() =>
{
res1 = Factorial(n1);
});
Thread t2 = new Thread(() => { res2=Factorial(n2); });
t1.Start();
t2.Start();
t1.Join();
t2.Join();
Console.WriteLine("Factorial of {0} equals {1}", n1, res1);
Console.WriteLine("Factorial of {0} equals {1}", n2, res2);
}
Run Code Online (Sandbox Code Playgroud)
输出:
Factorial of 5000 equals 0
Factorial of 10000 equals 0
Run Code Online (Sandbox Code Playgroud)
为什么这段代码返回0?
这是阶乘函数:
static long Factorial(long n)
{
long res = …Run Code Online (Sandbox Code Playgroud) 我的AsyncController中有以下异步方法:
public async Task<Dashboard> GetFeeds()
{
var movies = new HttpClient().GetStringAsync("http://netflix/api/MyMovies");
var tweets = new HttpClient().GetStringAsync("http://twitter/api/MyTweets");
await Task.WhenAll(movies, tweets);
Dashboard dash = new Dashboard();
dash.Movies = Deserialize<Movies >(movies.Result);
dash.Tweets = Deserialize<Tweets >(tweets.Result);
return dash;
}
Run Code Online (Sandbox Code Playgroud)
在这个方法中做不同的调用API,一个具有彼此不同的返回时间.我无法理解的Task<>是因为我必须等待两人的回归才能更新我的客户?因为我正在创造新的线程.

想象一下我在PartialView中播放每个API的返回,我认为结果会得到:
- 首先我会有我的电影列表(它只需要5s), - >显示给我的用户
- 然后我的推文列表 - >显示给我的用户
但我看到的是:
- 虽然Twitter请求没有结束,但我没有在屏幕上为我的用户播放我从Netflix获得的数据.
最大的问题是:A Task<>仅用于加快处理速度吗?
我根据我订购的每个API的周转时间无法在屏幕上播放信息?
这是对我的方法的调用
public async Task<ActionResult> Index()
{
var feeds = await GetFeeds();
return View(feeds);
}
Run Code Online (Sandbox Code Playgroud)
我承认,我很困惑,或者,也许你不明白这个概念Task<>.
简而言之,我有这样的事情:
class MyClass
{
double SomeProperty {get; private set;}
public async Task SomeMethod()
{
SomeProperty = await someService.SomeAsyncMethod();
}
}
Run Code Online (Sandbox Code Playgroud)
SomeProperty如果我SomeMethod()同时多次打电话可能会被破坏?
我读过,我应该只Result在await我绝对确定操作已完成时使用而不是使用。我不太确定下面会发生什么,想询问经验丰富的程序员这是否是await//Result的完全安全的用法async。
public static bool Success()
{
return 0 < Execute("DELETE FROM Table WHERE Id = 12").Result;
}
public static async Task<int> Execute(string sql)
{
using (var con = Connection)
{
con.Open();
return await con.ExecuteAsync(sql);
}
}
Run Code Online (Sandbox Code Playgroud) 我有一个应用程序,它不断(+-100 毫秒)从 PLC 读取订单,然后将它们放入一个模型中,然后由多个客户端读取。为此,我使用 lock 语句。
订单阅读线程:
lock (model) {
//update object
}
Run Code Online (Sandbox Code Playgroud)
客户阅读:
lock (model) {
//serialize object to json string
}
send over tcp stream to client.
Run Code Online (Sandbox Code Playgroud)
但我也可以用于更新:
Interlocked.ExChange(oldObj, newObj)
Run Code Online (Sandbox Code Playgroud)
我不希望我的客户必须等待订单读取线程中发生的锁定。而且我绝对不希望客户阻止我的订单阅读线程。
我最好使用 Interlocked 吗?
感谢您的建议!
我有一个要包装的函数,以便可以使用async / await模式:
wcfClientService.GetSomeString(parameter);
Run Code Online (Sandbox Code Playgroud)
这是来自WCF客户端的呼叫,我正在尝试使其异步,但这并不重要(我知道WCF支持异步,但是假设我们无权访问WCF代码)。
我正在尝试用该Task<T>.Factory.FromAsync方法包装该方法,但似乎无法正确处理它:
private Task<string> WrapWcfServiceAsyncTask(uint parameter)
{
Func<uint, string> func = i => { return wcfClientService.GetSomeString(parameter); };
var t = Task<string>.Factory.FromAsync(
// What goes here?
);
return t;
}
Run Code Online (Sandbox Code Playgroud)
甚至更好的是,有人可以编写一个将方法作为参数并包装并Task<T>为其返回的方法吗?
c# ×10
.net ×8
async-await ×8
asynchronous ×3
asp.net-mvc ×1
concurrency ×1
interlocked ×1
lambda ×1
locking ×1
task ×1
tpl-dataflow ×1
wcf ×1