小编Ste*_*ary的帖子

为什么System.Timers.Timer能够在GC中存活但不能在System.Threading.Timer中存活?

似乎System.Timers.Timer实例通过某种机制保持活跃,但System.Threading.Timer实例却没有.

示例程序,具有定期System.Threading.Timer和自动重置功能System.Timers.Timer:

class Program
{
  static void Main(string[] args)
  {
    var timer1 = new System.Threading.Timer(
      _ => Console.WriteLine("Stayin alive (1)..."),
      null,
      0,
      400);

    var timer2 = new System.Timers.Timer
    {
      Interval = 400,
      AutoReset = true
    };
    timer2.Elapsed += (_, __) => Console.WriteLine("Stayin alive (2)...");
    timer2.Enabled = true;

    System.Threading.Thread.Sleep(2000);

    Console.WriteLine("Invoking GC.Collect...");
    GC.Collect();

    Console.ReadKey();
  }
}
Run Code Online (Sandbox Code Playgroud)

当我运行这个程序(.NET 4.0 Client,Release,在调试器之外)时,只有System.Threading.TimerGC是:

Stayin alive (1)...
Stayin alive (1)...
Stayin alive (2)...
Stayin alive (1)...
Stayin …
Run Code Online (Sandbox Code Playgroud)

.net garbage-collection timer

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

使用Func委托与Async方法

我试图使用Func与异步方法.我收到了一个错误.

无法将异步lambda表达式转换为委托类型'Func<HttpResponseMesage>'.异步lambda表达式可能返回void,Task或者Task<T>都不能转换为'Func<HttpResponseMesage>'.

以下是我的代码:

public async Task<HttpResponseMessage> CallAsyncMethod()
{
    Console.WriteLine("Calling Youtube");
    HttpClient client = new HttpClient();
    var response = await client.GetAsync("https://www.youtube.com/watch?v=_OBlgSz8sSM");
    Console.WriteLine("Got Response from youtube");
    return response;
}

static void Main(string[] args)
{
    Program p = new Program();
    Task<HttpResponseMessage> myTask = p.CallAsyncMethod();
    Func<HttpResponseMessage> myFun =async () => await myTask;
    Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)

c# lambda asynchronous

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

等待基于任务的队列

我想知道是否存在ConcurrentQueue的实现/包装器,类似于BlockingCollection,其中从集合中获取不会阻塞,而是异步并且将导致异步等待直到将项目放入队列中.

我已经提出了自己的实现,但它似乎没有按预期执行.我想知道我是否正在重塑已经存在的东西.

这是我的实现:

public class MessageQueue<T>
{
    ConcurrentQueue<T> queue = new ConcurrentQueue<T>();

    ConcurrentQueue<TaskCompletionSource<T>> waitingQueue = 
        new ConcurrentQueue<TaskCompletionSource<T>>();

    object queueSyncLock = new object();

    public void Enqueue(T item)
    {
        queue.Enqueue(item);
        ProcessQueues();
    }

    public async Task<T> Dequeue()
    {
        TaskCompletionSource<T> tcs = new TaskCompletionSource<T>();
        waitingQueue.Enqueue(tcs);
        ProcessQueues();
        return tcs.Task.IsCompleted ? tcs.Task.Result : await tcs.Task;
    }

    private void ProcessQueues()
    {
        TaskCompletionSource<T> tcs=null;
        T firstItem=default(T);
        while (true)
        {
            bool ok;
            lock (queueSyncLock)
            {
                ok = waitingQueue.TryPeek(out tcs) && queue.TryPeek(out firstItem);
                if (ok)
                { …
Run Code Online (Sandbox Code Playgroud)

c# queue asynchronous async-await .net-4.5

33
推荐指数
5
解决办法
3万
查看次数

避免所有DI反模式需要异步初始化的类型

我有一个Connections需要异步初始化的类型.这种类型的实例被其他几种类型(例如Storage)消耗,每种类型也需要异步初始化(静态,不是每个实例,并且这些初始化也依赖于Connections).最后,我的逻辑类型(例如Logic)使用这些存储实例.目前使用Simple Injector.

我尝试了几种不同的解决方案,但总有一种反模式存在.


显式初始化(​​时间耦合)

我目前使用的解决方案有Temporal Coupling反模式:

public sealed class Connections
{
  Task InitializeAsync();
}

public sealed class Storage : IStorage
{
  public Storage(Connections connections);
  public static Task InitializeAsync(Connections connections);
}

public sealed class Logic
{
  public Logic(IStorage storage);
}

public static class GlobalConfig
{
  public static async Task EnsureInitialized()
  {
    var connections = Container.GetInstance<Connections>();
    await connections.InitializeAsync();
    await Storage.InitializeAsync(connections);
  }
}
Run Code Online (Sandbox Code Playgroud)

我已经将Temporal Coupling封装成一种方法,所以它并没有那么糟糕.但是,它仍然是一个反模式,而不是像我想的那样可维护.


抽象工厂(同步异步)

常见的解决方案是抽象工厂模式.但是,在这种情况下,我们正在处理异步初始化.因此,我可以通过强制初始化同步运行使用抽象工厂,但这会采用同步异步反模式.我真的不喜欢异步同步方法,因为我有几个存储空间,在我当前的代码中,它们都是同时初始化的; 由于这是一个云应用程序,将其更改为串行同步会增加启动时间,并且由于资源消耗,并行同步也不理想.


异步抽象工厂(不正确的抽象工厂用法)

我也可以使用Abstract Factory和异步工厂方法.但是,这种方法存在一个主要问题.正如马克·西曼(Mark …

dependency-injection initialization abstract-factory async-await simple-injector

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

为什么指针引用类型?

本周我一直在研究一些基于反射的代码,并且在单元测试期间发现了一个意外情况:指针是引用类型.C#代码typeof(int).MakePointerType().IsClass返回true.

我检查了刚刚到达的Annotated CLI标准,果然,指针被明确定义为引用类型.

这对我来说很奇怪,来自C++背景.我只是假设指针是值类型.

指针类型是引用类型而不是值类型是否有特殊原因?

更新(澄清)

在谈论指针和引用时,关于"指针"和"指针"的事情常常令人困惑.所以这里有一些澄清.

类型可以是引用类型或值类型,但变量有点不同.(对不起,我没有机会阅读我的CLI标准,因此术语和概念可能有误 - 请纠正我!)

给定此代码(引用类型的局部变量概念):

var x = new MyClass();
var y = x;
Run Code Online (Sandbox Code Playgroud)

变量xy实际上不是引用类型,但他们是一个对象,它是引用类型(引用MyClass是引用类型).换句话说,x并且y不是引用类型的实例; 它们只引用引用类型的实例.

给定此代码(值类型的局部变量概念):

var x = 13;
var y = x;
Run Code Online (Sandbox Code Playgroud)

变量xy实例值类型(或者至少就像它们的实例一样).

那么我们来看看这段代码:

var i = 13;
var x = &i;
var y = x;
Run Code Online (Sandbox Code Playgroud)

如果指针类型引用类型,那么这就是我解释语句的方式x = &i:

  1. int*创建一个类型的实例,指向i.
  2. 由于指针是引用类型,因此在堆上创建此实例(假设所有引用类型都放在堆上,这是一个实现细节). …

.net reflection

19
推荐指数
1
解决办法
848
查看次数

将Xamarin Forms视图渲染为Android视图,而不指定大小

我使用的是原生Xamarin.Android RecyclerView 在我的XAML作为描述在这里.RecyclerView管理屏幕上每个项目的一个视图(仅在我的应用程序中显示为垂直列表).如果我使用Xamarin.Android视图作为项目视图(在此示例中,a TextView),这可以正常工作:

public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
  var view = new TextView(parent.Context);
  return new TestViewHolder(view);
}
Run Code Online (Sandbox Code Playgroud)

但是,我真正想要做的是定义一个Xamarin.Forms控件并RecyclerView使用它.我可以使用内置的Android渲染器来获取Android视图,并且可以正常工作(即显示正确的数据):

public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
    var label = new Label { Text = "Hello!" };
    var cv = new ContentView
    {
        VerticalOptions = LayoutOptions.Start,
        HorizontalOptions = LayoutOptions.Start,
        Content = label,
    };
    var renderer = Xamarin.Forms.Platform.Android.Platform.CreateRendererWithContext(cv, parent.Context);
    var view = renderer.View;
    renderer.Tracker.UpdateLayout();
    view.LayoutParameters = …
Run Code Online (Sandbox Code Playgroud)

android xamarin xamarin.forms

17
推荐指数
1
解决办法
1146
查看次数

什么时候处理带有子任务的System.Threading.Task?

我有一个任务,启动几个子任务.(例如,任务A创建B,C,D,E,F).我还创建了System.Threading.Timer一个每10秒轮询一次数据库的程序,以检查计划项是否被请求取消.如果是,则设置CancellationTokenSource为任务知道取消.每个子任务(在本例中为B,C,D,E,F)将在适当时取消(它们通过文件循环并移动它们).

自从Task实现以来IDisposable,我想知道Task.WaitAllcatch块中再次调用是否是一个好主意,等待取消传播.在处理取消请求时,子任务可能处于循环的中间,并且在完成之前不能取消

但是,根据MSDN:

在释放对任务的最后一个引用之前,请始终调用Dispose.否则,在垃圾收集器调用Task对象的Finalize方法之前,不会释放它正在使用的资源.

我应该在我的任务数组上再次调用wait来正确调用数组中的Dispose()每个任务吗?

public class MyCancelObject
{
  CancellationTokenSource Source { get;set;}
  int DatabaseId { get;set;}   
}

private void CheckTaskCancelled(object state)
{
  MyCancelObject sourceToken = (MyCancelObject)state;

  if (!sourceToken.CancelToken.IsCancellationRequested)
  {
    //Check database to see if cancelled -- if so, set to cancelled
    sourceToken.CancelToken.Cancel();
  }
}

private void SomeFunc()
{
  Task.StartNew( () =>
  {
    MyCancelObject myCancelObject = new MyCancelObject(
      databaseId,
      new CancellationTokenSource());
    System.Threading.Timer cancelTimer = new Timer( …
Run Code Online (Sandbox Code Playgroud)

c# multithreading task

11
推荐指数
1
解决办法
2962
查看次数

我可以制作"密封除内部类型"之外的类型

我想创建一个可以从同一程序集中的类型继承的类型,但不能从程序集外部继承.我确实希望类型在程序集之外可见.

这可能吗?

c# internal sealed

10
推荐指数
1
解决办法
479
查看次数

自定义IExceptionHandler

我正在尝试IExceptionHandler使用我的Azure功能(C#类库).我的想法是拥有自己的异常处理程序,用于包含我自己的内存中跟踪日志的意外异常; 澄清一下,我确实希望将这些发送到客户端浏览器并显示给用户.

细节如下.

使用这个简单的自定义异常处理

public sealed class CustomExceptionHandler : ExceptionHandler
{
  public override void Handle(ExceptionHandlerContext context)
  {
    context.Result = new ResponseMessageResult(
        context.Request.CreateErrorResponse(HttpStatusCode.BadRequest,
            "custom message string"));
  }
}
Run Code Online (Sandbox Code Playgroud)

我试过安装它:

[FunctionName("Function1")]
public static HttpResponseMessage Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "works")]
    HttpRequestMessage req)
{
  req.GetConfiguration().Services.Replace(typeof(IExceptionHandler),
      new CustomExceptionHandler());
  throw new Exception("unexpected exception");
}
Run Code Online (Sandbox Code Playgroud)

但是在部署时,我只是得到通用的"操作失败"错误消息(例如,从Chrome格式化XML):

<ApiErrorModel xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Microsoft.Azure.WebJobs.Script.WebHost.Models">
  <Arguments xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" i:nil="true"/>
  <ErrorCode>0</ErrorCode>
  <ErrorDetails i:nil="true"/>
  <Id>dec07825-cf4e-49cc-a80e-bef0dbd01ba0</Id>
  <Message>An error has occurred. For more information, please check the logs for error ID dec07825-cf4e-49cc-a80e-bef0dbd01ba0</Message>
  <RequestId>51df1fec-c1c2-4635-b82c-b00d179d2e50</RequestId> …
Run Code Online (Sandbox Code Playgroud)

c# azure azure-functions

10
推荐指数
1
解决办法
451
查看次数

使用垃圾收集?

我想知道在调用Dispose()方法时执行了什么操作.Object在Dispose()调用或Dispose()上快速释放所有资源,标记Object已准备好进行垃圾回收.当我们将Object引用设置为NULL时发生了什么.实际上我在.NET 2.0中有Windows表单应用程序.并且我希望在经过一定时间后调用垃圾收集器(例如5分钟后)以收集所有未引用的对象.

c# garbage-collection dispose

8
推荐指数
2
解决办法
3718
查看次数