gho*_*ago 25 .net c# asynchronous
我在一个类似的对象构造函数中有一些代码
delegate DataSet MyInvoker;
public MyObject(Param1 p1)
{
// property sets here
// ...
BeginMyAsyncMethod();
}
public void BeginMyAsyncMethod()
{
// set some properties
// ...
MyInvoker inv = new MyInvoker(SomeBeginMethod);
inv.BeginInvoke(new AsyncCallback(SomeEndMethod), null);
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:
这个答案给我的印象是,将它留给用户是不好的做法,虽然我特别谈到在构造函数中启动异步方法,而不是正确构造对象.
Jer*_*xon 22
这可以通过稍微不同的方法轻松完成.在所有现实中,这种情况一直在发生,不是吗?这是一个简单的解决方案,为您提供一个选项,而不做一些愚蠢的事情:
public class MyResource
{
// do this instead of a constructor
public async Task<MyResource> StartAsync()
{
await Task.Delay(1);
return this;
}
}
public class MyControl
{
public MyResource Resource { get; set; }
async void Button_Click(object s, EventArgs e)
{
// call start as if it is a constructor
this.Resource = await new MyResource().StartAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
Tej*_*ejs 14
在构造函数中做一些与创建对象实例没有直接关系的东西通常不是一个好主意.例如,如果我不知道您的MyObject类的目的,我可能不知道它在创建新实例时会产生异步进程.这通常是一种不好的做法.
这几乎听起来像你在说; 嘿,创建这个对象,它只在这个异步过程完成后才可用; 这是违反直觉的.
如果你想做这样的事情,我认为通过工厂模式你肯定会得到更好的服务; 你这样叫一个工厂,它会创建对象并为你调用方法:
var instance = MyObjectBuilder.CreateInstance();
// Internally, this does
// var x = new MyObject();
// x.Initilizatize();
// return x;
Run Code Online (Sandbox Code Playgroud)
如果你的对象在完成初始化之前不可用,那么你应该暴露一个属性来检查它是否准备就绪,如下所示:
instance.WaitForReady(); // blocking version
if(instance.IsReady) // non blocking check
Run Code Online (Sandbox Code Playgroud)
是的,因为您可能会引入意外行为.应该构造对象,不受异常和意外行为的影响.如果在构造对象并且用户试图使用它之后仍然发生异步操作...
另外,如果异步方法仍在运行并且用户决定销毁该对象,该怎么办?
好读:http://www.amazon.com/Framework-Design-Guidelines-Conventions-Libraries/dp/0321545613/ref=sr_1_1?s= books& ie= UTF8& qid= 1314813265& sr=1-1
如果你的异步方法必须是异步的,因为它是一个长时间运行的进程,那么它需要被移动到它自己的方法,由用户调用,而不是在对象被实例化时.
如果用户在异步方法完成之前决定销毁它,这也意味着你可能有内存泄漏,那么你也有可能保持对该对象的引用.
如果要使用工厂或构建器创建初始化对象的HAS.
在完全构造实例之前,在构造函数中启动任何可能在另一个线程上调用实例的东西绝对是个坏主意.即使它的最后一行的构造函数,子类构造函数完成运行前,因为子类构造函数的代码基类的构造函数代码后运行回调可能被调用.即使您的课程今天已被密封,未来也可能未开封,如果将来添加子类,追踪此类问题很可能会非常昂贵.
基本上,如果你不想最终打猎heisenbugs,不要从构造函数中做过这类事情.相反,添加一个像你在问题#2中提到的"开始"方法.
我同意,不好主意.添加Initialize方法.您还可以添加一个返回新对象的静态方法并执行Initialize方法.通过这种方式,您还可以将构造函数保持为私有.
public class XXX
{
private XXX()
{
}
private void DoMyWeirdThingsAsynchronously()
{
....
}
public static XXX PerformSomethingStrange()
{
XXX result = new XXX();
result.DoMyWeirdThingsAsynchronously();
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17817 次 |
| 最近记录: |