小编ann*_*ijn的帖子

我应该升级为能够为SqlDataReader使用新的异步方法吗?

我正在研究一个在.NET 4.0上运行的大型项目.该框架使用ADO.NET进行数据库调用,我们目前正在添加异步API方法.该SqlCommand班有APM方法SqlCommand.BeginExecuteReader()SqlCommand.EndExecuteReader(),但SqlDataReader不具有异步实现.
SqlCommand.ExecuteReader()完成我想通过使用效果进行迭代SqlDataReader.Microsoft SqlDataReader在.NET 4.5中引入了异步方法,因此我不能在4.0中使用它们.

问题:我们应该升级才能使用异步(TAP)方法SqlDataReader吗?如果我们这样做,为什么?

我搜索了网络和stackoverflow很多答案,但我似乎只是找到了这个实现.它没有告诉我这些新实现给出了什么好处.

.NET 4.0实现

这里我们使用异步方法SqlCommand,但我们不能使用新的异步方法SqlDataReader,比如SqlDataReader.ReadAsync().

private Task<IDataReader> ExecuteReaderAsync(IDbCommand dbCommand)
{
    var sqlCommand = CheckIfSqlCommand(dbCommand);
    PrepareExecuteReader(dbCommand);

    return Task<IDataReader>
        .Factory
        .FromAsync(sqlCommand.BeginExecuteReader, sqlCommand.EndExecuteReader, null);
}

private void ReadAll(Task<IDataReader> readerTask)
{
    var reader = readerTask.Result;

    while (reader.Read()) // Should this be asynchronously?
    {
        // Do something
    }
}

public Task<IDataReader> Foo(IDbCommand dbCommand) { …
Run Code Online (Sandbox Code Playgroud)

.net c# asynchronous .net-4.0 .net-4.5

5
推荐指数
1
解决办法
2513
查看次数

任务取消和TaskContinuationOptions

我昨天刚刚介绍了Tasks(TPL),所以我尝试做一些示例项目,以便了解如何使用它们.

我的示例项目设置了一个开始按钮,开始递增进度条.第二个按钮取消任务.一个文本框用于报告何时调用使用TaskContinuationOptions.OnlyOnRanToCompletion的延续,以及一个文本框,用于报告何时调用使用TaskContinuationOptions.OnlyOnCanceled的继续.

我可以创建并执行一个Task,但是以一种让TaskContinuationOptions.OnlyOnCanceled标志继续触发的方式取消它是一个问题.

我创建如下任务:

private void StartTask()
{
    CancellationTokenSource tokenSource = new CancellationTokenSource();
    CancellationToken token = tokenSource.Token;

    Task task = null;
    task = Task.Factory.StartNew(() => DoWork(tokenSource), tokenSource.Token);

    //A list<CancellationTokenSource> so that I can cancel the task when clicking a button on the UI Thread.
    MyTasks.Add(tokenSource);

    Task completed = task.ContinueWith(result => TaskCompleted(), TaskContinuationOptions.OnlyOnRanToCompletion);
    Task canceled = task.ContinueWith(result => TaskCanceled(), TaskContinuationOptions.OnlyOnCanceled);
}
Run Code Online (Sandbox Code Playgroud)

我取消了以下任务:

private void CancelTasks()
{
    foreach (CancellationTokenSource tokenSource in MyTasks)
    {
        tokenSource.Cancel();                
    }
}
Run Code Online (Sandbox Code Playgroud)

我的工作人员功能如下:

private void DoWork(CancellationTokenSource tokenSource)
{ …
Run Code Online (Sandbox Code Playgroud)

c# task-parallel-library

4
推荐指数
1
解决办法
7253
查看次数

线程:不正确的变量传递C#

用户.我遇到了一个我无法找到答案的问题.我是Threading的新手(在C#中),遇到了这个问题.我有这个带有效果的图像编辑器,但由于它运行得太慢,我试图将其拆分为线程.问题是他总是使用效果列表中的最后一项运行"CreatePreview"命令.因此,如果我激活了效果:"黑/白","Sature"和"GreenFilter",它将尝试使用greenfilter创建3个预览.

任何人都可以帮我解决这个问题吗?

private void CreatePreviews(string fileName, List<IEffect> effects)
{
    List<Task> tasks = new List<Task>();
    foreach (var effect in effects)
    {
        //previews.Add(effect, CreatePreview(fileName, effect));
        Task task = new Task(delegate()
        {
            string result = CreatePreview(fileName, effect);
            Dispatcher.BeginInvoke(new Action(
            delegate()
            {
                ShowPreview(result, effect.DisplayName);
            }));

        });
        task.Start();
    }
}
Run Code Online (Sandbox Code Playgroud)

c# variables multithreading

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

如何并行读取队列中的消息?

情况

我们有一个消息队列.我们希望并行处理消息并限制同时处理的消息的数量.

我们下面的试用代码会并行处理消息,但只有在完成上一个流程时才会启动新批处理.我们想在完成后重启任务.

换句话说:只要消息队列不为空,任务的最大数量应始终处于活动状态.

试用代码

static string queue = @".\Private$\concurrenttest";

private static void Process(CancellationToken token)
{
    Task.Factory.StartNew(async () =>
    {
        while (true)
        {
            IEnumerable<Task> consumerTasks = ConsumerTasks();
            await Task.WhenAll(consumerTasks);

            await PeekAsync(new MessageQueue(queue));
        }
    });
}

private static IEnumerable<Task> ConsumerTasks()
{
    for (int i = 0; i < 15; i++)
    {
        Command1 message;
        try
        {
            MessageQueue msMq = new MessageQueue(queue);
            msMq.Formatter = new XmlMessageFormatter(new Type[] { typeof(Command1) });
            Message msg = msMq.Receive();
            message = (Command1)msg.Body;
        }
        catch (MessageQueueException mqex)
        {
            if …
Run Code Online (Sandbox Code Playgroud)

.net c# parallel-processing message-queue task-parallel-library

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