当我遇到这种特殊情况时,我正在实现同步/异步重载:
当我有一个没有参数或返回值的常规lambda表达式时,它会Run使用Action参数进行重载,这是可预测的.但是当lambda中有一个lambda时,while (true)它会通过Func参数进入重载状态.
public void Test()
{
Run(() => { var name = "bar"; });
Run(() => { while (true) ; });
}
void Run(Action action)
{
Console.WriteLine("action");
}
void Run(Func<Task> func) // Same behavior with Func<T> of any type.
{
Console.WriteLine("func");
}
Run Code Online (Sandbox Code Playgroud)
输出:
动作
功能
那怎么可能呢?有原因吗?
我想澄清一下使用Await和Async的额外好处是什么.
如果我的应用程序正在调用await Func1()(这里没有阻止UI).并且Func1正在等待Func2(),但结果Func2()对于Func1完成它的工作很重要,那么为什么我需要Func2()等待.Func1()执行将花费同样长的时间,因为它正在等待Func2完成.await所做的就是添加StateMachine开销.
我在这里错过了什么吗?
在C#6中,新字符串插值的默认文化是什么?
我已经看到了关于Invariant和Current Culture的相互矛盾的报道.
我希望得到一个明确的答案,我会不停地指责Invariant.
好的,我的问题非常简单.为什么这段代码不会抛出TaskCancelledException?
static void Main()
{
var v = Task.Run(() =>
{
Thread.Sleep(1000);
return 10;
}, new CancellationTokenSource(500).Token).Result;
Console.WriteLine(v); // this outputs 10 - instead of throwing error.
Console.Read();
}
Run Code Online (Sandbox Code Playgroud)
但这一个有效
static void Main()
{
var v = Task.Run(() =>
{
Thread.Sleep(1000);
return 10;
}, new CancellationToken(true).Token).Result;
Console.WriteLine(v); // this one throws
Console.Read();
}
Run Code Online (Sandbox Code Playgroud) .net c# task-parallel-library cancellationtokensource cancellation-token
我使用传递的取消令牌,以便可以干净地关闭我的服务.该服务具有不断尝试连接到其他服务的逻辑,因此令牌是打破在单独线程中运行的这些重试循环的好方法.我的问题是我需要调用一个具有内部重试逻辑的服务,但是如果重试失败则在一段时间后返回.我想创建一个带有超时的新取消令牌,这将为我做到这一点.这个问题是我的新令牌没有链接到"主"令牌,所以当主令牌被取消时,我的新令牌仍然有效,直到它超时或建立连接并返回.我想要做的是将两个令牌链接在一起,这样当主要的一个被取消时,我的新一个也会取消.我尝试使用该CancellationTokenSource.CreateLinkedTokenSource方法但是当我的新令牌超时时,它也取消了主令牌.有没有办法做我需要做的令牌,或者它需要更改重试逻辑(可能不会轻易做到这一点)
这是我想要做的:
主令牌 - 传递各种功能,以便服务可以干净地关闭.临时令牌 - 传递给单个函数并在一分钟后设置为超时
如果取消主令牌,则还必须取消临时令牌.
当临时令牌到期时,它不得取消主令牌.
这里的证明.
知道这段代码有什么问题吗?
[TestMethod]
public void TestTest()
{
var tcp = new TcpClient() { ReceiveTimeout = 5000, SendTimeout = 20000 };
tcp.Connect(IPAddress.Parse("176.31.100.115"), 25);
bool ok = Read(tcp.GetStream()).Wait(30000);
Assert.IsTrue(ok);
}
async Task Read(NetworkStream stream)
{
using (var cancellationTokenSource = new CancellationTokenSource(5000))
{
int receivedCount;
try
{
var buffer = new byte[1000];
receivedCount = await stream.ReadAsync(buffer, 0, 1000, cancellationTokenSource.Token);
}
catch (TimeoutException e)
{
receivedCount = -1;
}
}
}
Run Code Online (Sandbox Code Playgroud) 我已经创建了一小段代码来并行运行多个异步操作(Parallel该类本身不适合异步操作).
它看起来像这样:
public static async Task ForEachAsync<T>(this IEnumerable<T> source, int dop, Func<T, Task> body)
{
var chunks = source.Chunk(dop);
foreach (var chunk in chunks)
await Task.WhenAll(chunk.Select(async s => await body(s).ContinueWith(t => ThrowError(t))));
}
private static IEnumerable<IEnumerable<T>> Chunk<T>(this IEnumerable<T> source, int chunksize)
{
while (source.Any())
{
yield return source.Take(chunksize);
source = source.Skip(chunksize);
}
}
private static void ThrowError(Task t)
{
if (t.IsFaulted)
{
if (t.Exception.InnerExceptions != null && t.Exception.InnerExceptions.Count == 1)
throw t.Exception.InnerExceptions[0];
else
throw t.Exception;
}
}
Run Code Online (Sandbox Code Playgroud)
就并行运行任务而言,上述代码运行良好.但是,在抛出异常时,我会遇到一些问题. …
我有各种任务的令牌,我需要更好地管理他们的取消,以获得我可以使用的取消通知:
token.Register(RegisterMethod);
Run Code Online (Sandbox Code Playgroud)
如何删除此"订阅"?有没有办法"UnRegister"?
我想过用TaskCompletionSource做一个解决方法.但我不知道它是否会运作良好.解决这种方法的最佳方法是什么?
看看CancellationToken.None它的实现,它只是回归default(CancellationToken).但是,我在CancellationToken文档中看不到两者是等价的.
我想提供这样的API,但直到我确定它总能工作:
Task DoSomething(CancellationToken token = default(CancellationToken))
Run Code Online (Sandbox Code Playgroud)
它定义的行为default(CancellationToken)是否相同CancellationToken.None,或者这只是一个实现细节?
请问.NET框架的async内置库/组件,它可以与文件系统的工作(例如File.ReadAllBytes,File.WriteAllBytes)?
还是我用我自己写的库async的方法StreamReader和StreamWriter?
像这样的东西会很不错:
var bytes = await File.ReadAllBytes("my-file.whatever");
Run Code Online (Sandbox Code Playgroud) c# ×8
.net ×6
async-await ×5
asynchronous ×2
.net-4.5 ×1
ado.net ×1
async-ctp ×1
c#-6.0 ×1
filesystems ×1
lambda ×1
linq ×1
overloading ×1
sockets ×1
task ×1