似乎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) 我试图使用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) 我想知道是否存在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) 我有一个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
本周我一直在研究一些基于反射的代码,并且在单元测试期间发现了一个意外情况:指针是引用类型.C#代码typeof(int).MakePointerType().IsClass返回true.
我检查了刚刚到达的Annotated CLI标准,果然,指针被明确定义为引用类型.
这对我来说很奇怪,来自C++背景.我只是假设指针是值类型.
指针类型是引用类型而不是值类型是否有特殊原因?
更新(澄清)
在谈论指针和引用时,关于"指针"和"指针"的事情常常令人困惑.所以这里有一些澄清.
类型可以是引用类型或值类型,但变量有点不同.(对不起,我没有机会阅读我的CLI标准,因此术语和概念可能有误 - 请纠正我!)
给定此代码(引用类型的局部变量概念):
var x = new MyClass();
var y = x;
Run Code Online (Sandbox Code Playgroud)
变量x和y实际上不是引用类型,但他们是一个对象,它是引用类型(引用MyClass是引用类型).换句话说,x并且y不是引用类型的实例; 它们只引用引用类型的实例.
给定此代码(值类型的局部变量概念):
var x = 13;
var y = x;
Run Code Online (Sandbox Code Playgroud)
变量x和y实例值类型(或者至少就像它们的实例一样).
那么我们来看看这段代码:
var i = 13;
var x = &i;
var y = x;
Run Code Online (Sandbox Code Playgroud)
如果指针类型是引用类型,那么这就是我解释语句的方式x = &i:
int*创建一个类型的实例,指向i.我使用的是原生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) 我有一个任务,启动几个子任务.(例如,任务A创建B,C,D,E,F).我还创建了System.Threading.Timer一个每10秒轮询一次数据库的程序,以检查计划项是否被请求取消.如果是,则设置CancellationTokenSource为任务知道取消.每个子任务(在本例中为B,C,D,E,F)将在适当时取消(它们通过文件循环并移动它们).
自从Task实现以来IDisposable,我想知道Task.WaitAll从catch块中再次调用是否是一个好主意,等待取消传播.在处理取消请求时,子任务可能处于循环的中间,并且在完成之前不能取消
但是,根据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) 我想创建一个可以从同一程序集中的类型继承的类型,但不能从程序集外部继承.我确实希望类型在程序集之外可见.
这可能吗?
我正在尝试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) 我想知道在调用Dispose()方法时执行了什么操作.Object在Dispose()调用或Dispose()上快速释放所有资源,标记Object已准备好进行垃圾回收.当我们将Object引用设置为NULL时发生了什么.实际上我在.NET 2.0中有Windows表单应用程序.并且我希望在经过一定时间后调用垃圾收集器(例如5分钟后)以收集所有未引用的对象.