小编i3a*_*non的帖子

定期以指定的时间间隔运行异步方法

我需要从C#Web应用程序向服务发布一些数据.用户使用应用程序时会收集数据本身(一种使用情况统计信息).我不希望在每个用户的请求期间向服务发送数据,我宁愿在应用程序中收集数据,然后在一个单独的线程中发送单个请求中的所有数据,这不会满足用户的请求(我的意思是用户不必等待服务处理请求).为此,我需要一种JS的setInterval模拟 - 每隔X秒启动一次函数,将所有收集的数据刷新到服务中.

我发现Timer该类提供了一些类似的(Elapsed事件).但是,这允许只运行一次方法,但这不是一个大问题.它的主要困难是需要签名

void MethodName(object e, ElapsedEventArgs args)
Run Code Online (Sandbox Code Playgroud)

虽然我想启动异步方法,它将调用web服务(输入参数并不重要):

async Task MethodName(object e, ElapsedEventArgs args)
Run Code Online (Sandbox Code Playgroud)

任何人都可以建议如何解决所描述的任务?任何提示赞赏.

.net c# asp.net multithreading async-await

16
推荐指数
3
解决办法
3万
查看次数

C#async等待使用LINQ ForEach()

我有以下代码正确使用async/await范例.

internal static async Task AddReferencseData(ConfigurationDbContext context)
{
    foreach (var sinkName in RequiredSinkTypeList)
    {
        var sinkType = new SinkType() { Name = sinkName };
        context.SinkTypeCollection.Add(sinkType);
        await context.SaveChangesAsync().ConfigureAwait(false);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果不是使用foreach(),我想使用LINQ ForEach(),那么写这个的等效方法是什么?例如,这个给出了编译错误.

internal static async Task AddReferenceData(ConfigurationDbContext context)
{
    RequiredSinkTypeList.ForEach(
        sinkName =>
        {
            var sinkType = new SinkType() { Name = sinkName };
            context.SinkTypeCollection.Add(sinkType);
            await context.SaveChangesAsync().ConfigureAwait(false);
        });
}
Run Code Online (Sandbox Code Playgroud)

我没有编译错误的唯一代码就是这个.

internal static void AddReferenceData(ConfigurationDbContext context)
{
    RequiredSinkTypeList.ForEach(
        async sinkName =>
        {
            var sinkType = new SinkType() { Name = sinkName };
            context.SinkTypeCollection.Add(sinkType); …
Run Code Online (Sandbox Code Playgroud)

.net c# linq async-await

15
推荐指数
2
解决办法
1万
查看次数

TaskCompletionSource抛出"尝试将任务转换为已完成的最终状态"

我想用来TaskCompletionSource包装MyService哪个是简单的服务:

public static Task<string> ProcessAsync(MyService service, int parameter)
{
    var tcs = new TaskCompletionSource<string>();
    //Every time ProccessAsync is called this assigns to Completed!
    service.Completed += (sender, e)=>{ tcs.SetResult(e.Result); };   
    service.RunAsync(parameter);
    return tcs.Task;
}
Run Code Online (Sandbox Code Playgroud)

这段代码第一次运行良好.但是我第二ProcessAsync简单地Completed再次调用事件处理程序(service每次使用相同的变量),因此它将执行两次!并且它第二次抛出此异常:

在已经完成时尝试转换任务最终状态

我不确定,我应该tcs像这样声明一个类级变量:

TaskCompletionSource<string> tcs;

public static Task<string> ProccessAsync(MyService service, int parameter)
{
    tcs = new TaskCompletionSource<string>();
    service.Completed -= completedHandler; 
    service.Completed += completedHandler;
    return tcs.Task;    
}

private void completedHandler(object sender, CustomEventArg e)
{ …
Run Code Online (Sandbox Code Playgroud)

.net c# asynchronous async-await taskcompletionsource

15
推荐指数
2
解决办法
1万
查看次数

Task.WaitAll不等待任务完成

在试图找出新的(现在可能不是那么新,但对我而言是新的)TaskC#中的异步编程时,我遇到了一个问题,让我有点想弄清楚,我不知道为什么.

我已经解决了这个问题,但我仍然不确定为什么这是一个问题.我只是觉得我会分享我的经验,以防任何人遇到同样的情况.

如果有任何大师想告诉我这个问题的原因,那就太棒了,非常感激.我总是喜欢知道为什么有些东西不起作用!

我做了一个测试任务,如下:

Random rng = new Random((int)DateTime.UtcNow.Ticks);
int delay = rng.Next(1500, 15000);
Task<Task<object>> testTask = Task.Factory.StartNew<Task<object>>(
    async (obj) =>
        {
            DateTime startTime = DateTime.Now;
            Console.WriteLine("{0} - Starting test task with delay of {1}ms.", DateTime.Now.ToString("h:mm:ss.ffff"), (int)obj);
            await Task.Delay((int)obj);
            Console.WriteLine("{0} - Test task finished after {1}ms.", DateTime.Now.ToString("h:mm:ss.ffff"), (DateTime.Now - startTime).TotalMilliseconds);
            return obj;
        },
        delay
    );
Task<Task<object>>[] tasks = new Task<Task<object>>[] { testTask };

Task.WaitAll(tasks);
Console.WriteLine("{0} - Finished waiting.", DateTime.Now.ToString("h:mm:ss.ffff"));

// make console stay open till user …
Run Code Online (Sandbox Code Playgroud)

.net c# task-parallel-library async-await .net-4.5

15
推荐指数
2
解决办法
1万
查看次数

CancellationToken取消不会破坏BlockingCollection

我有这样的取消令牌

   static CancellationTokenSource TokenSource= new CancellationTokenSource();
Run Code Online (Sandbox Code Playgroud)

我有一个像这样的阻止集合

BlockingCollection<object> items= new BlockingCollection<object>();

var item = items.Take(TokenSource.Token);

if(TokenSource.CancelPending)
   return;
Run Code Online (Sandbox Code Playgroud)

我打电话的时候

TokenSource.Cancel();
Run Code Online (Sandbox Code Playgroud)

Take不会像它应该的那样继续下去.如果我使用带轮询的TryTake,令牌显示它被设置为已取消.

c# collections parallel-processing cancellation-token

14
推荐指数
1
解决办法
7323
查看次数

Task.Delay永远不会完成

以下代码将永远冻结.

public async Task DoSomethingAsync()
{
    await Task.Delay(2000);
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    DoSomethingAsync().Wait();
    // Task.Delay(2000).Wait();
}
Run Code Online (Sandbox Code Playgroud)

如果我DoSomethingAsync使用注释掉的代码切换调用,它的行为与预期一致.我怀疑嵌套等待导致死锁,但我不知道为什么,或者如何解决它.

.net c# delay task-parallel-library async-await

14
推荐指数
1
解决办法
3290
查看次数

如何创建一个空的IReadOnlyCollection

我正在为MultiValueDictionary创建一个扩展方法来封装频繁的ContainsKey检查,我想知道什么是创建空的最佳方法IReadOnlyCollection

我一直使用至今的new List<TValue>(0).AsReadOnly(),但必须有一个更好的办法,一个equivilant来IEnumerableEnumerable.Empty

public static IReadOnlyCollection<TValue> GetValuesOrEmpty<TKey, TValue>(this MultiValueDictionary<TKey, TValue> multiValueDictionary, TKey key)
{            
    IReadOnlyCollection<TValue> values;
    return !multiValueDictionary.TryGetValue(key, out values) ? new List<TValue>(0).AsReadOnly() : values;
}
Run Code Online (Sandbox Code Playgroud)

.net c# readonly-collection multi-value-dictionary

14
推荐指数
2
解决办法
6113
查看次数

在非异步方法中使用async

让我们说我只想要一种方法来运行async.

所以我有一个async如下方法:

public async Task Load(){
    Task task1 = GetAsync(1);
    Task task2 = GetAsync(2);
    Task task3 = GetAsync(3);
    var data1 = await task1; // <--Freezes here when called from GetSomethingElse()
    var data2 = await task2;
    var data3 = await task3;
    ..process data..
}
Run Code Online (Sandbox Code Playgroud)

然后我试图async在另一个方法中将该方法称为任务,并希望它等到特定的async代码片段完成.问题是它不是.当它到达第一个时await,Load()它就没有完成加载.调试器变为空白,不会出现其他错误.

是一种async能够从非async方法调用的方法吗?有一个原因我不需要这个特定的任务async,但Load()我做的功能.

public void GetSomethingElse(){
    var task1 = Load().Wait();      
}
Run Code Online (Sandbox Code Playgroud)

这怎么可能?


我试过甚至改变Load()使用的方法var data = …

.net c# asp.net asynchronous async-await

14
推荐指数
1
解决办法
1061
查看次数

将任务作为参数传递

我不确定这是否可行,所以我在这里:

我有一系列动作来执行多个

async Task MethodA(...)
{
    // some code
    // a call to specific Async IO bound method
    // some code
}
Run Code Online (Sandbox Code Playgroud)

还有MethodB(),MethodC()等,以及所有的具有完全相同的代码,除了呼叫到特定的异步IO绑定的方法.我试图找到一种方法将任务指针传递给方法,以便我们稍后可以在Method()中执行它.

我目前正在做的是:

private async Task Method(Func<Task<Entity>> func)
{
    // some code
    var a = await task.Run(func);
    // some code
}

var task = async () => await CallToIOBoundTask(params);
Method(task);
Run Code Online (Sandbox Code Playgroud)

但是,此代码每次都会提取一个新线程,这对于IO绑定任务不是必需的,应该避免使用.

那么,有没有办法重构代码,以便不使用ThreadPool线程?目标是拥有这样的代码:

private async Task Method(Task<Entity> task)
{
    // some code
    var a = await task;
    // some code
}
Run Code Online (Sandbox Code Playgroud)

同样重要的是要提到不同的IO调用具有不同的方法签名.此外,任务可以开始仅在Method()正文中执行,而不是之前执行.

.net c# task-parallel-library async-await .net-4.5

14
推荐指数
1
解决办法
9242
查看次数

在MongoDB .NET Driver 2.0中查找所有

我想查询我的MongoDB集合而没有使用MongoDB .NET Driver 2.0的任何过滤器,但我找不到办法.我有以下解决方法,但看起来很奇怪:D

var filter = Builders<FooBar>.Filter.Exists(x => x.Id);
var fooBars = await _fooBarCollection.Find(filter)
    .Skip(0)
    .Limit(100)
    .ToListAsync();
Run Code Online (Sandbox Code Playgroud)

有没有办法在MongoDB .NET Driver 2.0中没有过滤器的情况下发出查询?

.net c# mongodb mongodb-csharp-2.0 mongodb-.net-driver

13
推荐指数
1
解决办法
7105
查看次数