标签: task-parallel-library

与异步lambda并行的foreach

我想并行处理一个集合,但是我在实现它时遇到了麻烦,因此我希望得到一些帮助.

如果我想在并行循环的lambda中调用C#中标记为async的方法,则会出现问题.例如:

var bag = new ConcurrentBag<object>();
Parallel.ForEach(myCollection, async item =>
{
  // some pre stuff
  var response = await GetData(item);
  bag.Add(response);
  // some post stuff
}
var count = bag.Count;
Run Code Online (Sandbox Code Playgroud)

计数为0时会出现问题,因为创建的所有线程实际上只是后台线程,并且Parallel.ForEach调用不等待完成.如果我删除async关键字,该方法如下所示:

var bag = new ConcurrentBag<object>();
Parallel.ForEach(myCollection, item =>
{
  // some pre stuff
  var responseTask = await GetData(item);
  responseTask.Wait();
  var response = responseTask.Result;
  bag.Add(response);
  // some post stuff
}
var count = bag.Count;
Run Code Online (Sandbox Code Playgroud)

它工作,但它完全禁用等待聪明,我必须做一些手动异常处理..(为简洁起见删除).

如何实现一个Parallel.ForEach在lambda中使用await关键字的循环?可能吗?

Parallel.ForEach方法的原型采用Action<T>as参数,但我希望它等待我的异步lambda.

c# task-parallel-library async-await parallel.foreach

100
推荐指数
6
解决办法
7万
查看次数

通过等待任务或访问其Exception属性,未观察到任务的异常.结果,未观察到的例外是

这意味着什么以及如何解决它?

我正在使用TPL任务.

整个错误

通过等待任务或访问其Exception属性,未观察到任务的异常.结果,终结器线程重新抛出了未观察到的异常.

在System.Threading.Tasks.TaskExceptionHolder.Finalize()

mscorlib程序

c# wpf exception task task-parallel-library

97
推荐指数
2
解决办法
4万
查看次数

当前的SynchronizationContext可能不会用作TaskScheduler

我正在使用Tasks在我的ViewModel中运行长时间运行的服务器调用,结果将被重新编组Dispatcher使用TaskScheduler.FromSyncronizationContext().例如:

var context = TaskScheduler.FromCurrentSynchronizationContext();
this.Message = "Loading...";
Task task = Task.Factory.StartNew(() => { ... })
            .ContinueWith(x => this.Message = "Completed"
                          , context);
Run Code Online (Sandbox Code Playgroud)

这在我执行应用程序时工作正常.但是当我运行我的NUnit测试时,Resharper我在调用时收到错误消息FromCurrentSynchronizationContext:

当前的SynchronizationContext可能不会用作TaskScheduler.

我想这是因为测试是在工作线程上运行的.如何确保测试在主线程上运行?欢迎任何其他建议.

c# multithreading nunit task-parallel-library resharper-6.0

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

为什么这个异步操作会挂起?

我有一个多层.Net 4.5应用程序调用一个方法使用C#的新asyncawait关键字挂起,我不明白为什么.

在底部我有一个异步方法来扩展我们的数据库实用程序OurDBConn(基本上是底层DBConnectionDBCommand对象的包装器):

public static async Task<T> ExecuteAsync<T>(this OurDBConn dataSource, Func<OurDBConn, T> function)
{
    string connectionString = dataSource.ConnectionString;

    // Start the SQL and pass back to the caller until finished
    T result = await Task.Run(
        () =>
        {
            // Copy the SQL connection so that we don't get two commands running at the same time on the same open connection
            using (var ds = new OurDBConn(connectionString))
            {
                return function(ds);
            } …
Run Code Online (Sandbox Code Playgroud)

c# asynchronous task-parallel-library async-await c#-5.0

96
推荐指数
4
解决办法
5万
查看次数

是否建议将prevTask.Wait()与ContinueWith一起使用(来自Tasks库)?

所以我最近被告知我如何使用我的.ContinueWith for Tasks并不是使用它们的正确方法.我还没有在互联网上找到这方面的证据,所以我会问你们,看看答案是什么.这是我如何使用的例子.ContinueWith:

public Task DoSomething()
{
    return Task.Factory.StartNew(() =>
    {
        Console.WriteLine("Step 1");
    })
    .ContinueWith((prevTask) =>
    {
        Console.WriteLine("Step 2");
    })
    .ContinueWith((prevTask) =>
    {
        Console.WriteLine("Step 3");
    });
}
Run Code Online (Sandbox Code Playgroud)

现在我知道这是一个简单的例子,它运行得非常快,但只是假设每个任务都进行了更长时间的操作.所以,我被告知在.ContinueWith中,你需要说prevTask.Wait(); 否则你可以在上一个任务完成之前完成工作.这甚至可能吗?我假设我的第二个和第三个任务只会在前一个任务完成后运行.

我被告知如何编写代码:

public Task DoSomething()
{
    return Task.Factory.StartNew(() =>
    {
        Console.WriteLine("Step 1");
    })
    .ContinueWith((prevTask) =>
    {
        prevTask.Wait();
        Console.WriteLine("Step 2");
    })
    .ContinueWith((prevTask) =>
    {
        prevTask.Wait();
        Console.WriteLine("Step 3");
    });
}
Run Code Online (Sandbox Code Playgroud)

c# task-parallel-library

88
推荐指数
4
解决办法
9万
查看次数

导致死锁的异步/等待示例

我发现了一些使用c#async/ awaitkeywords的异步编程的最佳实践(我是c#5.0的新手).

给出的建议之一是:

稳定性:了解同步上下文

...某些同步上下文是不可重入和单线程的.这意味着在给定时间内只能在上下文中执行一个工作单元.一个例子是Windows UI线程或ASP.NET请求上下文.在这些单线程同步上下文中,很容易使自己陷入僵局.如果从单线程上下文中生成任务,然后在上下文中等待该任务,则等待代码可能会阻止后台任务.

public ActionResult ActionAsync()
{
    // DEADLOCK: this blocks on the async task
    var data = GetDataAsync().Result;

    return View(data);
}

private async Task<string> GetDataAsync()
{
    // a very simple async method
    var result = await MyWebService.GetDataAsync();
    return result.ToString();
}
Run Code Online (Sandbox Code Playgroud)

如果我自己尝试剖析它,主线程会产生一个新线程MyWebService.GetDataAsync();,但由于主线程在那里等待,它等待结果GetDataAsync().Result.同时,说数据准备好了.为什么主线程不继续它的延续逻辑并从中返回字符串结果GetDataAsync()

有人可以解释一下为什么上面的例子中存在死锁吗?我完全不知道问题是什么......

c# deadlock task-parallel-library async-await c#-5.0

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

在c#4.0中执行fire and forget方法的最简单方法

我真的很喜欢这个问题:

在C#中执行fire and forget方法的最简单方法是什么?

我只是想知道,现在我们在C#4.0中有并行扩展,是否有更好的更简洁的方法来使用并行linq进行Fire&Forget?

.net c# .net-4.0 task-parallel-library fire-and-forget

86
推荐指数
4
解决办法
5万
查看次数

实现永无止境任务的正确方法.(计时器与任务)

因此,只要应用程序正在运行或请求取消,我的应用程序几乎需要连续执行操作(每次运行之间暂停10秒左右).它需要做的工作可能需要30秒.

是否更好地使用System.Timers.Timer并使用AutoReset确保它在前一个"tick"完成之前不执行操作.

或者我应该在LongRunning模式下使用带有取消令牌的常规任务,并且在其内部有一个常规的无限while循环调用在调用之间使用10秒Thread.Sleep执行工作的操作?至于async/await模型,我不确定它在这里是否合适,因为我没有任何工作的返回值.

CancellationTokenSource wtoken;
Task task;

void StopWork()
{
    wtoken.Cancel();

    try 
    {
        task.Wait();
    } catch(AggregateException) { }
}

void StartWork()
{
    wtoken = new CancellationTokenSource();

    task = Task.Factory.StartNew(() =>
    {
        while (true)
        {
            wtoken.Token.ThrowIfCancellationRequested();
            DoWork();
            Thread.Sleep(10000);
        }
    }, wtoken, TaskCreationOptions.LongRunning);
}

void DoWork()
{
    // Some work that takes up to 30 seconds but isn't returning anything.
}
Run Code Online (Sandbox Code Playgroud)

或者只是在使用AutoReset属性时使用简单的计时器,并调用.Stop()取消它?

c# multithreading timer task-parallel-library .net-4.5

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

是否有基于任务的System.Threading.Timer替换?

我是.Net 4.0的任务的新手,我无法找到我认为基于任务的替换或实现定时器,例如定期任务.有这样的事吗?

更新 我提出了我认为是我的需求的解决方案,即将"计时器"功能包装在具有子任务的任务中,所有任务都利用CancellationToken并返回任务以便能够参与进一步的任务步骤.

public static Task StartPeriodicTask(Action action, int intervalInMilliseconds, int delayInMilliseconds, CancellationToken cancelToken)
{ 
    Action wrapperAction = () =>
    {
        if (cancelToken.IsCancellationRequested) { return; }

        action();
    };

    Action mainAction = () =>
    {
        TaskCreationOptions attachedToParent = TaskCreationOptions.AttachedToParent;

        if (cancelToken.IsCancellationRequested) { return; }

        if (delayInMilliseconds > 0)
            Thread.Sleep(delayInMilliseconds);

        while (true)
        {
            if (cancelToken.IsCancellationRequested) { break; }

            Task.Factory.StartNew(wrapperAction, cancelToken, attachedToParent, TaskScheduler.Current);

            if (cancelToken.IsCancellationRequested || intervalInMilliseconds == Timeout.Infinite) { break; }

            Thread.Sleep(intervalInMilliseconds);
        }
    };

    return Task.Factory.StartNew(mainAction, cancelToken);
}      
Run Code Online (Sandbox Code Playgroud)

c# timeout timer .net-4.0 task-parallel-library

84
推荐指数
5
解决办法
6万
查看次数

BackgroundWorker的任务并行库替换?

任务并行库是否有任何可以被认为是对BackgroundWorker类的替换或改进?

我有一个带有向导式UI的WinForms应用程序,它执行一些长时间运行的任务.我希望能够使用标准进度条和取消操作的响应式UI.我之前用BackgroundWorker做过这个,但是我想知道是否有一些可以使用的TPL模式?

c# backgroundworker winforms task-parallel-library

82
推荐指数
2
解决办法
4万
查看次数