标签: task-parallel-library

在主UI线程的Continuation中,SynchronizationContext.Current为null

我一直在试图追查了以下问题的WinForms应用程序:
SynchronizationContext.Current是一个任务的延续(即空.ContinueWith这是主要的线程上运行)(我预计当前同步上下文是System.Windows.Forms.WindowsFormsSynchronizationContext).

以下是演示此问题的Winforms代码:

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            TaskScheduler ts = TaskScheduler.FromCurrentSynchronizationContext(); // Get the UI task scheduler

            // This line is required to see the issue (Removing this causes the problem to go away), since it changes the codeflow in 
            // \SymbolCache\src\source\.NET\4\DEVDIV_TFS\Dev10\Releases\RTMRel\ndp\clr\src\BCL\System\Threading\ExecutionContext.cs\1305376\ExecutionContext.cs
            // at line 435
            System.Diagnostics.Trace.CorrelationManager.StartLogicalOperation("LogicalOperation");

            var task = Task.Factory.StartNew(() => { });
            var cont …
Run Code Online (Sandbox Code Playgroud)

c# winforms synchronizationcontext task-parallel-library

21
推荐指数
1
解决办法
5809
查看次数

有没有办法将任务并行库(TPL)与SQLDataReader一起使用?

我喜欢TPL中Parallel.For和Parallel.ForEach扩展方法的简单性.我想知道是否有办法利用类似的东西,甚至是稍微高级的任务.

下面是SqlDataReader的典型用法,我想知道是否可能,如果是这样,如何用TPL中的东西替换下面的while循环.因为读者不能提供固定数量的迭代,所以不能使用For扩展方法,这样就可以处理我将收集的任务.我希望有人可能已经解决了这个问题,然后找出了一些与ADO.net不同的事情.

using (SqlConnection conn = new SqlConnection("myConnString"))
using (SqlCommand comm = new SqlCommand("myQuery", conn))
{
    conn.Open();

    SqlDataReader reader = comm.ExecuteReader();

    if (reader.HasRows)
    {
        while (reader.Read())
        {
            // Do something with Reader
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

c# ado.net .net-4.0 task-parallel-library

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

TPL TaskFactory.FromAsync vs任务与阻塞方法

我想知道在使用TPL TaskFactory.FromAsync和使用TaskFactory.StartNew阻塞版本的方法之间是否存在性能影响.我正在编写一个TCP服务器,它将支持不超过100个并发连接.在使用第一个选项编写代码并使用continue来链接多个读写操作之后,我留下了丑陋,难以调试的代码.

我相信用同步版本编写代码然后用Task包装它会降低复杂性并提高可测试性,但是我担心这样做的性能影响.

例如,这两个调用之间是否存在任何性能差异:

NetworkStream stream;
byte[] data;
int bytesRead;

//using FromAsync
Task<int> readChunk = Task<int>.Factory.FromAsync (
      stream.BeginRead, stream.EndRead,
      data, bytesRead, data.Length - bytesRead, null);

//using StartNew with blocking version
Task<int> readChunk2 = Task<int>.Factory.StartNew(() => 
      stream.Read(data, bytesRead, data.Length - bytesRead));
Run Code Online (Sandbox Code Playgroud)

networkstream task task-parallel-library taskfactory c#-4.0

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

TPL Dataflow,如何将项目转发到许多链接目标块中的一个特定目标块?

我正在寻找一个TPL数据流块解决方案,它可以容纳多个项目,可以链接到多个目标块,但是它能够将项目转发到仅通过过滤器/谓词的特定目标块.在任何时候都不应该将项目同时传递到多个目标块,始终只能传递给与过滤器匹配的项目,或者可以丢弃该项目.我不喜欢BroadCastBlock,因为如果我理解正确,它不能保证传送(或者是吗?)并且过滤是在目标块侧完成的,这意味着BroadCastBlock基本上将每个项目的副本发送到所有linkedTo目标块.如果我理解正确,它也不会在任何时候持有多个项目.我不想使用Post/Async但维护LinkTo链.

有没有办法绕过完整的自定义数据流块?或者我误解了BroadCastBlock的工作原理?不幸的是,实际上没有太多文档可以详细介绍并涵盖用例.任何想法都受到高度赞赏.

c# message-passing task-parallel-library actor tpl-dataflow

20
推荐指数
2
解决办法
5403
查看次数

为什么在使用当前同步上下文启动任务时未设置ASP.NET HttpContext.Current

我正在玩一点.NET的异步功能,并提出了一个我无法解释的情况.在同步ASP.NET MVC控制器中执行以下代码时

var t = Task.Factory.StartNew(()=>{
        var ctx = System.Web.HttpContext.Current;
        //ctx == null here
},
    CancellationToken.None,
    TaskCreationOptions.None,
    TaskScheduler.FromCurrentSynchronizationContext()
);

t.Wait();
Run Code Online (Sandbox Code Playgroud)

ctxnull委托范围内.根据我的理解,当您使用TaskScheduler.FromCurrentSynchronizationContext()任务调度程序时,应该恢复上下文.那么为什么不在这里呢?(我可以,顺便说一下,看到委托在同一个线程上同步执行).

此外,从msdn,a TaskScheduler.FromCurrentSynchronizationContext()应该表现如下:

排队到返回的调度程序的所有Task实例将通过在该上下文上调用Post方法来执行.

但是,当我使用此代码时:

var wh = new AutoResetEvent(false);

SynchronizationContext.Current.Post(s=> {
    var ctx = System.Web.HttpContext.Current;
    //ctx is set here
    wh.Set();
    return;
},null);

wh.WaitOne();
Run Code Online (Sandbox Code Playgroud)

实际上设置了上下文.

我知道这个例子有点做作,但我真的很想了解如何增加我对.NET上异步编程的理解.

.net asp.net asynchronous task-parallel-library

20
推荐指数
2
解决办法
6850
查看次数

通过等待每个任务异步转换IEnumerable <Task <T >>

今天我想知道如何通过等待每个任务来转换任务列表.请考虑以下示例:

private static void Main(string[] args)
{
    try
    {
        Run(args);                
        Console.ReadLine();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
        Console.ReadLine();
    }
}

static async Task Run(string[] args)
{
    //Version 1: does compile, but ugly and List<T> overhead
    var tasks1 = GetTasks();                       

    List<string> gainStrings1 = new List<string>();
    foreach (Task<string> task in tasks1)
    {
        gainStrings1.Add(await task);
    }
    Console.WriteLine(string.Join("", gainStrings1));

    //Version 2: does not compile
    var tasks2 = GetTasks();
    IEnumerable<string> gainStrings2 = tasks2.Select(async t => await t);
    Console.WriteLine(string.Join("", gainStrings2));
}

static IEnumerable<Task<string>> GetTasks()
{
    string[] …
Run Code Online (Sandbox Code Playgroud)

c# linq task-parallel-library async-await

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

将长时间运行的任务与async/await模式结合起来的正确方法是什么?

我有一个"高精度"计时器类,我需要能够启动,停止和暂停/恢复.为此,我将在互联网上找到的几个不同的例子捆绑在一起,但我不确定我是否正在使用asnyc/await正确的任务.

这是我的相关代码:

//based on http://haukcode.wordpress.com/2013/01/29/high-precision-timer-in-netc/
public class HighPrecisionTimer : IDisposable
{
    Task _task;
    CancellationTokenSource _cancelSource;

    //based on http://blogs.msdn.com/b/pfxteam/archive/2013/01/13/cooperatively-pausing-async-methods.aspx
    PauseTokenSource _pauseSource;

    Stopwatch _watch;
    Stopwatch Watch { get { return _watch ?? (_watch = Stopwatch.StartNew()); } }

    public bool IsPaused
    {
        get { return _pauseSource != null && _pauseSource.IsPaused; }
        private set
        {
            if (value)
            {
                _pauseSource = new PauseTokenSource();
            }
            else
            {
                _pauseSource.IsPaused = false;
            }
        }
    }

    public bool IsRunning { get { return !IsPaused && _task != null && …
Run Code Online (Sandbox Code Playgroud)

c# long-running-processes xamarin.ios task-parallel-library async-await

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

默认SynchronizationContext与默认TaskScheduler

这会有点长,所以请耐心等待.

我在想默认任务scheduler(ThreadPoolTaskScheduler)的行为与默认的" ThreadPool" SynchronizationContext(后者可以通过await或显式地通过隐式引用)非常相似TaskScheduler.FromCurrentSynchronizationContext().它们都安排在随机ThreadPool线程上执行的任务.实际上,SynchronizationContext.Post只是打电话ThreadPool.QueueUserWorkItem.

但是,TaskCompletionSource.SetResult当从默认排队的任务中使用时,工作方式有一个微妙但重要的区别SynchronizationContext.这是一个简单的控制台应用程序说明它:

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleTcs
{
    class Program
    {
        static async Task TcsTest(TaskScheduler taskScheduler)
        {
            var tcs = new TaskCompletionSource<bool>();

            var task = Task.Factory.StartNew(() =>
                {
                    Thread.Sleep(1000);
                    Console.WriteLine("before tcs.SetResult, thread: " + Thread.CurrentThread.ManagedThreadId);
                    tcs.SetResult(true);
                    Console.WriteLine("after tcs.SetResult, thread: " + Thread.CurrentThread.ManagedThreadId);
                    Thread.Sleep(2000);
                },
                CancellationToken.None,
                TaskCreationOptions.None,
                taskScheduler);

            Console.WriteLine("before await tcs.Task, thread: " + Thread.CurrentThread.ManagedThreadId);
            await tcs.Task.ConfigureAwait(true); …
Run Code Online (Sandbox Code Playgroud)

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

20
推荐指数
1
解决办法
9105
查看次数

Await或Task.FromResult

我有一个服务可以说,

public interface ISomeService
{
    Task<bool> DoSomeExpensiveCheckAsync(string parameter);
}
Run Code Online (Sandbox Code Playgroud)

我有这个课程来消费服务.它只需要做一些简单的空检查,然后返回服务响应.

public class SomeServiceConsumer
{
    private readonly ISomeService _serviceClient;

    public SomeServiceConsumer(ISomeService serviceClient)
    {
        _serviceClient = serviceClient;
    }

    public async Task<bool> DoSomething1Async(string someParameter)
    {
        if (string.IsNullOrWhiteSpace(someParameter))
        {
            return false;
        }
        return await _serviceClient.DoSomeExpensiveCheckAsync(someParameter);
    }

    //No async or await keywords   
    public Task<bool> DoSomething2Async(string someParameter)
    {
        if (string.IsNullOrWhiteSpace(someParameter))
        {
            return Task.FromResult(false);
        }
        return _serviceClient.DoSomeExpensiveCheckAsync(someParameter);
    }
}
Run Code Online (Sandbox Code Playgroud)

我应该做的DoSomething1Async还是DoSomething2Async

根据这个答案,我不应该用不必要的东西包裹await但是我必须Task.FromResult(false)用于短路DoSomething2Async

但根据这个答案,有一些案例try/catch和 …

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

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

await在异步操作后没有恢复上下文?

我已经 从Noseratio那里读到了这个问题,这个问题显示了一个在等待完成其操作之后TaskScheduler.Current一样的行为.

答案指出:

如果没有执行任何实际任务,则与之TaskScheduler.Current 相同TaskScheduler.Default

这是真的.我已在这里看到它 :

  • TaskScheduler.Default
    • 返回一个实例 ThreadPoolTaskScheduler
  • TaskScheduler.Current
    • 如果从执行任务中调用将返回TaskScheduler 当前正在执行的任务
    • 如果从任何其他地方打电话将返回 TaskScheduler.Default

但转念一想,如果是这样,让我们创建一个实际的Task(不只是Task.Yield()),并对其进行测试:

async void button1_Click_1(object sender, EventArgs e)
{
    var ts = TaskScheduler.FromCurrentSynchronizationContext();
    await Task.Factory.StartNew(async () =>
    {
        MessageBox.Show((TaskScheduler.Current == ts).ToString()); //True

           await new WebClient().DownloadStringTaskAsync("http://www.google.com");

        MessageBox.Show((TaskScheduler.Current == ts).ToString());//False

    }, CancellationToken.None, TaskCreationOptions.None,ts).Unwrap();
}
Run Code Online (Sandbox Code Playgroud)

第一个Messagebox是"True",第二个是"False"

题:

如您所见,我确实创建了一个实际任务.

我可以理解为什么第一个MessageBox产量True.多数民众赞成:

如果从执行任务中调用,则返回当前正在执行的任务的TaskScheduler

而那个任务确实有ts发送的内容 …

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

20
推荐指数
1
解决办法
745
查看次数