我有时会使用一组任务,为了确保它们都在等待我使用这种方法:
public async Task ReleaseAsync(params Task[] TaskArray)
{
var tasks = new HashSet<Task>(TaskArray);
while (tasks.Any()) tasks.Remove(await Task.WhenAny(tasks));
}
Run Code Online (Sandbox Code Playgroud)
然后像这样调用它:
await ReleaseAsync(task1, task2, task3);
//or
await ReleaseAsync(tasks.ToArray());
Run Code Online (Sandbox Code Playgroud)
但是,最近我注意到了一些奇怪的行为,并设置了ReleaseAsync方法是否存在问题.我设法将它缩小到这个简单的演示,如果你包含它,它将在linqpad中运行System.Threading.Tasks.它也可以在控制台应用程序或asp.net mvc控制器中稍作修改.
async void Main()
{
Task[] TaskArray = new Task[]{run()};
var tasks = new HashSet<Task>(TaskArray);
while (tasks.Any<Task>()) tasks.Remove(await Task.WhenAny(tasks));
}
public async Task<int> run()
{
return await Task.Run(() => {
Console.WriteLine("started");
throw new Exception("broke");
Console.WriteLine("complete");
return 5;
});
}
Run Code Online (Sandbox Code Playgroud)
我不明白为什么异常永远不会出现在任何地方.我想如果等待具有异常的任务,它就会抛出.我能够通过用这样的简单替换while循环来确认这一点:
foreach( var task in TaskArray )
{
await task;//this will throw …Run Code Online (Sandbox Code Playgroud) 我正在开发一个C#项目,并希望利用UnhandledException事件来捕获我在项目中可能遗漏的任何异常(希望不会有任何异常,但是在同一方面).
我制作了相当多的软件,所以我想创建一个我的所有项目都会使用的类库,所以我希望有一个函数可以完成我所有项目的所有初始化工作,而无需复制和粘贴代码进入每个项目做同样的工作.
我想知道的是,如果我在类库中使用以下代码处理未处理的异常事件
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(currentDomain_UnhandledException);
Run Code Online (Sandbox Code Playgroud)
未处理的异常是否仅在类库中使用,或者此事件句柄是否也可以从引用类库的任何项目中执行.
感谢您的任何帮助,您可以提供.
传统意义上没有返回值优化,但我想知道你何时遇到这样的情况:
private async Task Method1()
{
await Method2();
}
private async Task Method2()
{
await Method3();
}
private async Task Method3()
{
//do something async
}
Run Code Online (Sandbox Code Playgroud)
这显然可以更好地编写:
private Task Method1()
{
return Method2();
}
private Task Method2()
{
return Method3();
}
private async Task Method3()
{
//do something async
}
Run Code Online (Sandbox Code Playgroud)
我只是想知道是否有人知道,如果(MS)编译器很聪明不够而产生状态机Method1(),并Method2()在第一时间?
我见过的一个常见问题是管理任务中未处理的异常.它们不会导致崩溃,它们会无声地发生,我甚至无法在任务失败时触发事件!我已经看到用户开出自定义类和处理这个的东西,我的问题是,是否有一种"标准"的微软方式来处理这个问题?
为了举例,我制作了这个简单的控制台应用程序(.NET 4.5.1)来演示这个问题.是否可以修改这些任务以便可以异步执行这些任务,但在遇到未处理的异常时调用"handler"?或者至少崩溃?我认为这就是UnobservedTaskException应该做的事情.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
TaskScheduler.UnobservedTaskException += Handler;
AppDomain.CurrentDomain.UnhandledException += Handler;
Task.Run(() => { throw new ApplicationException("I'll throw an unhandled exception"); });
Task.Factory.StartNew(() => { throw new ApplicationException("I'll throw an unhandled exception too"); });
System.Threading.Thread.Sleep(2000);
Console.WriteLine("I think everything is just peachy!");
System.Threading.Thread.Sleep(10000);
}
private static void Handler(Object sender, EventArgs e)
{
Console.WriteLine("I'm so lonely, won't anyone call me?");
}
}
} …Run Code Online (Sandbox Code Playgroud) 我正在我的窗口中执行异步任务:
private async Task LoadData()
{
// Fetch data
var data = await FetchData();
// Display data
// ...
}
Run Code Online (Sandbox Code Playgroud)
该窗口在单独的线程中启动:
// Create and run new thread
var thread = new Thread(ThreadMain);
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = true;
thread.CurrentCulture = Thread.CurrentThread.CurrentCulture;
thread.CurrentUICulture = Thread.CurrentThread.CurrentUICulture;
thread.Start();
private static void ThreadMain()
{
// Set synchronization context
var dispatcher = Dispatcher.CurrentDispatcher;
SynchronizationContext.SetSynchronizationContext(
new DispatcherSynchronizationContext(dispatcher));
// Show window
var window = new MyWindow();
window.ShowDialog();
// Shutdown
dispatcher.InvokeShutdown();
}
Run Code Online (Sandbox Code Playgroud)
当窗户关闭时,线程当然已经完成,这很好.
现在 - 如果在FetchData完成之前发生这种情况,我会得到内存泄漏.
似乎FetchData …
我有一个场景,我创建任务作为 Webapi 调用的一部分。当任务中发生异常时,它不会被捕获,并且我不知道如何为此实现全局异常处理程序。
尤其:
如果您认为上述任何一项应该有效,请告诉我,我将针对我所观察到的情况提出一个可重复的小示例。否则,这样做的正确方法是什么?
[HttpGet]
public IQueryable<Thingies> Thingies()
{
Task.Run(() => { throw new ApplicationException("How do I catch all of these globally?"); });
return _db.Thingies;
}
Run Code Online (Sandbox Code Playgroud)
我还应该注意的是,该应用程序没有依赖项System.Web,我不想介绍它们。
我遇到了以下有关何时何地使用的文章ConfigureAwait(false),但无法得到答案。
您不需要 ConfigureAwait(false),但仍可在库和 UI 应用程序中使用它。(例如 Xamarin、WinForms 等)
https://blog.stephencleary.com/2017/03/aspnetcore-synchronization-context.html
此链接说相反的答案
为所有服务器端代码调用 ConfigureAwait 的最佳实践
我的问题:
场景 1:下面的代码作为后台服务运行。
我的问题:ConfigureAwait(false)无论何时await都需要像下面的 A 和 B 一样使用:
[Service(Name = "com.MainApplicationService", Label = "Main Application Service", Exported = false)]
public class MainApplicationService : Android.App.Service
{
public override IBinder OnBind(Intent intent)
{
return null;
}
[return: GeneratedEnum]
public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
{
await InitAsync().ConfigureAwait(false); //line A
Task.Run(async () => await …Run Code Online (Sandbox Code Playgroud) c# task-parallel-library xamarin.android async-await xamarin
在我的Windows Phone 8.1应用程序中,我有一个单件服务DataService,应该偶尔下载一些数据.同时在UI上我应该显示收到的数据量.当用户登录应用程序时,将调用DataService.StartGettingData():
void StartGettingData()
{
if (getDataTaskCancellationTokenSource != null)
getDataTaskCancellationTokenSource.Cancel();
getDataTaskCancellationTokenSource = new CancellationTokenSource();
var token = getDataTaskCancellationTokenSource.Token;
Task.Factory.StartNew(async () => await ExecuteCycleAsync(token), token);
}
async Task ExecuteCycleAsync(CancellationToken cancellationToken)
{
while (true)
{
cancellationToken.ThrowIfCancellationRequested();
await LoadDataAsync(cancellationToken);
cancellationToken.ThrowIfCancellationRequested();
await Task.Delay(timeTillNextDownload, cancellationToken);
}
}
Run Code Online (Sandbox Code Playgroud)
当用户在帮助下注销时,此任务将被取消
if (getDataTaskCancellationTokenSource != null)
getDataTaskCancellationTokenSource.Cancel();
Run Code Online (Sandbox Code Playgroud)
包含下载结果的属性如下所示:
List<DataType> Data = new List<DataType>();
public IEnumerable<DataType> Data
{
get { return Data; }
set
{
Data = value.ToList();
OnDataUpdated();
}
}
void OnDataUpdated()
{
var handler = DataUpdated;
if …Run Code Online (Sandbox Code Playgroud)