标签: task-parallel-library

如果在没有完成任务的情况下超时,Task.Wait(int)是否会停止任务?

我有一个任务,我希望它能在一秒钟内运行,但是如果需要的时间超过几秒钟,我想取消任务.

例如:

Task t = new Task(() =>
        {
            while (true)
            {
                Thread.Sleep(500);
            }
        });
t.Start();
t.Wait(3000);
Run Code Online (Sandbox Code Playgroud)

请注意,等待3000毫秒后,等待到期.超时到期或任务是否仍在运行时,任务是否被取消?

.net c# multithreading task task-parallel-library

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

使用带有条件延续的任务

我对如何使用条件Continuations的任务感到困惑.

如果我有一个任务,然后我想继续处理成功和错误的任务,然后等待那些完成.

void FunctionThrows() {throw new Exception("faulted");}

static void MyTest()
{

    var taskThrows = Task.Factory.StartNew(() => FunctionThrows());

    var onSuccess = taskThrows.ContinueWith(
                          prev => Console.WriteLine("success"), 
                          TaskContinuationOptions.OnlyOnRanToCompleted);

    var onError = taskThrows.ContinueWith(
                          prev => Console.WriteLine(prev.Exception),
                          TaskContinuationOptions.OnlyOnFaulted);

    //so far, so good



    //this throws because onSuccess was cancelled before it was started
    Task.WaitAll(onSuccess, onError);
}
Run Code Online (Sandbox Code Playgroud)

这是执行任务成功/失败分支的首选方式吗?另外,我应该如何加入所有这些任务,假设我已经创建了一长串的延续,每个延续都有自己的错误处理.

  //for example
  var task1 = Task.Factory.StartNew(() => ...)
  var task1Error = task1.ContinueWith(  //on faulted
  var task2  = task1.ContinueWith(      //on success
  var task2Error = task2.ContinueWith(  //on faulted
  var task3 = …
Run Code Online (Sandbox Code Playgroud)

c# .net-4.0 task-parallel-library

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

优雅地处理任务取消

当我需要能够取消大型/长期运行工作负载的任务时,我经常使用与此类似的模板执行任务:

public void DoWork(CancellationToken cancelToken)
{
    try
    {
        //do work
        cancelToken.ThrowIfCancellationRequested();
        //more work
    }
    catch (OperationCanceledException)
    {
        throw;
    }
    catch (Exception ex)
    {
        Log.Exception(ex);
        throw;
    }
}
Run Code Online (Sandbox Code Playgroud)

不应将OperationCanceledException记录为错误,但如果任务要转换为已取消状态,则不得吞下OperationCanceledException.除了此方法的范围之外,不需要处理任何其他异常.

这总觉得有点笨重,默认情况下visual studio会在OperationCanceledException的中断(虽然因为我使用了这种模式,我已经'关闭了User-unhandled'现在关闭了OperationCanceledException).

理想情况下,我认为我希望能够做到这样的事情:

public void DoWork(CancellationToken cancelToken)
{
    try
    {
        //do work
        cancelToken.ThrowIfCancellationRequested();
        //more work
    }
    catch (Exception ex) exclude (OperationCanceledException)
    {
        Log.Exception(ex);
        throw;
    }
}
Run Code Online (Sandbox Code Playgroud)

即将某种排除列表应用于捕获但没有当前不可能的语言支持(@ eric-lippert:c#vNext feature :)).

另一种方式是通过延续:

public void StartWork()
{
    Task.Factory.StartNew(() => DoWork(cancellationSource.Token), cancellationSource.Token)
        .ContinueWith(t => Log.Exception(t.Exception.InnerException), TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously);
}

public void DoWork(CancellationToken cancelToken)
{
    //do …
Run Code Online (Sandbox Code Playgroud)

c# exception-handling task-parallel-library

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

等待AutoResetEvent

什么是AutoResetEvent的异步(等待)等价物?

如果在经典线程同步中我们会使用这样的东西:

    AutoResetEvent signal = new AutoResetEvent(false);

    void Thread1Proc()
    {
        //do some stuff
        //..
        //..

        signal.WaitOne(); //wait for an outer thread to signal we are good to continue

        //do some more stuff
        //..
        //..
    }

    void Thread2Proc()
    {
        //do some stuff
        //..
        //..

        signal.Set(); //signal the other thread it's good to go

        //do some more stuff
        //..
        //..
    }
Run Code Online (Sandbox Code Playgroud)

我希望以新的异步方式做事,这样的事情会变成:

SomeAsyncAutoResetEvent asyncSignal = new SomeAsyncAutoResetEvent();

async void Task1Proc()
{
    //do some stuff
    //..
    //..

    await asyncSignal.WaitOne(); //wait for an outer …
Run Code Online (Sandbox Code Playgroud)

.net c# multithreading asynchronous task-parallel-library

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

如果发生任何异常,如何使Task.WaitAll()中断?

如果任何正在运行的任务抛出异常,我想让Task.WaitAll()爆发,这样我就不必等待60秒才能完成.我该如何实现这种行为?如果WaitAll()无法实现,那么还有其他c#功能或解决方法吗?

Task task1 = Task.Run(() => throw new InvalidOperationException());
Task task2 = ...
...
try
{
    Task.WaitAll(new Task[]{task1, task2, ...}, TimeSpan.FromSeconds(60));
}
catch (AggregateException)
{
    // If any exception thrown on any of the tasks, break out immediately instead of wait all the way to 60 seconds.
}
Run Code Online (Sandbox Code Playgroud)

c# task task-parallel-library async-await

30
推荐指数
1
解决办法
7270
查看次数

Task.WhenAll结果排序

我从这里理解,任务执行顺序Task.Whenall不是确定性的,但我找不到任何有关结果顺序的信息.

结果集合是否按照输入中排序的任务或结果的顺序包含结果?

从我做的测试来看,它似乎保留了订单,但我需要确认.

c# parallel-processing concurrency asynchronous task-parallel-library

30
推荐指数
1
解决办法
5015
查看次数

何时使用TaskCreationOptions.LongRunning?

我很想知道这一点,但从未真正找到答案.

我知道这是任务调度程序的一个提示,任务调度程序将在其中运行,并且任务调度程序可以(或现在将?)决定为该任务实例化非线程池线程.

我不知道(并且令人惊讶地在互联网上找不到)是一个"经验法则"何时指定一个长期运行的任务.是一秒多长?30秒?一分钟?5分钟?它是否与应用程序使用的任务量有关系?作为程序员,我应该使用线程池中的#threads进行一些计算,我创建了多少个任务,同时长时间运行了多少个任务,并根据这个来决定是否使用长时间运行的任务?

希望在这里学点东西.

c# multithreading task task-parallel-library

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

列出<T>线程安全

我使用以下代码

var processed = new List<Guid>();
Parallel.ForEach(items, item => 
{
    processed.Add(SomeProcessingFunc(item));
});
Run Code Online (Sandbox Code Playgroud)

上面的代码线程是否安全?处理后的列表是否有可能被破坏?或者我应该在添加之前使用锁?

var processed = new List<Guid>();
Parallel.ForEach(items, item => 
{
    lock(items.SyncRoot)
        processed.Add(SomeProcessingFunc(item));
});
Run Code Online (Sandbox Code Playgroud)

谢谢.

c# list parallel-extensions task-parallel-library c#-4.0

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

在C#中使用async而不等待?

考虑在没有等待的情况下使用async.

想想也许你误解了异步的作用.警告是完全正确的:如果您将方法标记为异步但不在任何地方使用等待,那么您的方法将不是异步的.如果调用它,方法中的所有代码将同步执行.

我想编写一个应该运行异步但不需要使用await的方法.例如,当使用线程时

public async Task PushCallAsync(CallNotificationInfo callNotificationInfo)
{
    Logger.LogInfo("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId,
}
Run Code Online (Sandbox Code Playgroud)

我想要调用PushCallAsync并运行异步,不想使用等待.

我可以在C#中使用async而无需等待吗?

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

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

将ManualResetEvent包装为等待任务

我想等待手动重置事件,超时并观察取消.我想出了类似下面的东西.手动重置事件对象由我无法控制的API提供.有没有办法在不接受和阻止ThreadPool线程的情况下实现这一点?

static Task<bool> TaskFromWaitHandle(WaitHandle mre, int timeout, CancellationToken ct)
{
    return Task.Run(() =>
    {
        bool s = WaitHandle.WaitAny(new WaitHandle[] { mre, ct.WaitHandle }, timeout) == 0;
        ct.ThrowIfCancellationRequested();
        return s;
    }, ct);
}

// ...

if (await TaskFromWaitHandle(manualResetEvent, 1000, cts.Token))
{
    // true if event was set
}
else 
{
    // false if timed out, exception if cancelled 
}
Run Code Online (Sandbox Code Playgroud)

将帖子显然,这是有道理的使用RegisterWaitForSingleObject.我试试看.

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

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