我最近创建了这两个(不相关的)方法来替换我的winforms应用程序中的大量样板代码.据我所知,他们工作正常,但我需要一些保证/建议,以确定是否存在一些我可能会遗漏的问题.
(从记忆里)
static class SafeInvoker
{
//Utility to avoid boiler-plate InvokeRequired code
//Usage: SafeInvoker.Invoke(myCtrl, () => myCtrl.Enabled = false);
public static void Invoke(Control ctrl, Action cmd)
{
if (ctrl.InvokeRequired)
ctrl.BeginInvoke(new MethodInvoker(cmd));
else
cmd();
}
//Replaces OnMyEventRaised boiler-plate code
//Usage: SafeInvoker.RaiseEvent(this, MyEventRaised)
public static void RaiseEvent(object sender, EventHandler evnt)
{
var handler = evnt;
if (handler != null)
handler(sender, EventArgs.Empty);
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:请在此处查看相关问题
UPDATE
继死锁问题(在此问题中相关)之后,我已从Invoke切换到BeginInvoke(请参阅此处的解释).
另一个更新
关于第二个片段,我越来越倾向于使用'空委托'模式,通过使用空处理程序直接声明事件来解决"源"问题,如下所示:
event EventHandler MyEventRaised = delegate {};
Run Code Online (Sandbox Code Playgroud) 图表1:一些代码将Async(不是async!)网络调用包装成一个Task
public static Task<byte[]> GetAsync(IConnection connection, uint id)
{
ReadDataJob jobRDO = new ReadDataJob();
//No overload of FromAsync takes 4 extra parameters, so we have to wrap
// Begin in a Func so that it looks like it takes no parameters except
// callback and state
Func<AsyncCallback, object, IAsyncResult> wrapped = (callback, state) =>
jobRDO.Begin(connection, 0, 0, id, callback, state);
return Task<byte[]>.Factory.FromAsync(wrapped, ar =>
{
ErrorCode errorCode;
UInt32 sError;
UInt32 attribute;
byte[] data = new byte[10];
jobRDO.End(out …Run Code Online (Sandbox Code Playgroud) 乱用List模块的"扩展功能".(我花了很长时间开发'mapfold' - 它将一个累加器像fold折叠,但是使用它作为参数来创建像map这样的新值 - 然后发现那是什么List.scan_left)
为了生成测试数据,我需要做两个列表的交叉产品,这就是我提出的:
///Perform cross product of two lists, return tuple
let crossproduct l1 l2 =
let product lst v2 = List.map (fun v1 -> (v1, v2)) lst
List.map_concat (product l1) l2
Run Code Online (Sandbox Code Playgroud)
这有什么好处,还是有更好的方法来做到这一点?
同样的问题:
///Perform cross product of three lists, return tuple
let crossproduct3 l1 l2 l3 =
let tuplelist = crossproduct l1 l2 //not sure this is the best way...
let product3 lst2 v3 = List.map (fun (v1, v2) -> (v1, v2, v3)) lst2 …Run Code Online (Sandbox Code Playgroud) 我有一个creaky属性映射的接口:
interface IPropertyMap
{
bool Exists(string key);
int GetInt(string key);
string GetString(string key);
//etc..
}
Run Code Online (Sandbox Code Playgroud)
我想创建一个像这样的扩展方法:
public static T GetOrDefault<T>(this IPropertyMap map, string key, T defaultValue)
{
if (!map.Exists(key))
return defaultValue;
else
{
if (typeof(T) == typeof(int)) return (T)map.GetInt(key);
//etc..
}
}
Run Code Online (Sandbox Code Playgroud)
但编译器不会让我转向T.我尝试添加,where T : struct但似乎没有帮助.
我错过了什么?
在困惑我的代码一段时间后,我发现异常不一定传播通过ContinueWith:
int zeroOrOne = 1;
Task.Factory.StartNew(() => 3 / zeroOrOne)
.ContinueWith(t => t.Result * 2)
.ContinueWith(t => Console.WriteLine(t.Result))
.ContinueWith(_ => SetBusy(false))
.LogExceptions();
Run Code Online (Sandbox Code Playgroud)
在这个例子中,该SetBusy行"复位"异常链,所以通过零异常的鸿沟是没有看到,随后在我的脸炸毁"任务的异常(S),未观察到......"
所以......我给自己写了一个小扩展方法(有很多不同的重载,但基本上都是这样做的):
public static Task ContinueWithEx(this Task task, Action<Task> continuation)
{
return task.ContinueWIth(t =>
{
if(t.IsFaulted) throw t.Exception;
continuation(t);
});
}
Run Code Online (Sandbox Code Playgroud)
周围多一点搜索,我碰到这个博客帖子,在那里,他提出了一个类似的解决方案,但使用TaskCompletionSource,其中(转述)看起来是这样的:
public static Task ContinueWithEx(this Task task, Action<Task> continuation)
{
var tcs = new TaskCompletionSource<object>();
return task.ContinueWith(t =>
{
if(t.IsFaulted) tcs.TrySetException(t.Exception);
continuation(t);
tcs.TrySetResult(default(object));
});
return tcs.Task;
} …Run Code Online (Sandbox Code Playgroud) 如果我右键单击项目中的文件夹并执行TortoiseSVN->重命名,它会考虑一段时间,然后告诉我Can't move X to Y: Access Denied.但是从同事的机器上它运行正常,我可以重命名文件没问题.是什么赋予了?
尽管它有效,但我开始严重怀疑OpenID社区.
我正在将OpenID评估为"这个"网站的身份验证服务,虽然承诺很好,但我无法让它工作.我真的迷路了.
我要求SO社区帮助我.给我答案并向我展示示例,以便我可以按照预期的方式利用它.
我的场景非常典型.我想通过特定的Google Apps域对用户进行身份验证.如果您有权访问此Google Apps域,则可以访问我的Web应用程序.
在我迷路的地方,涉及所有先决条件和依赖关系.
而且,这对我来说非常重要.
当我登录SO时,我使用我的Google帐户.当我点击登录按钮时,我会看到此确认页面.我授予SO使用我的Google帐户凭据的权利.
不知何故,Google知道它是"Stackoverflow.com",它问我是否可以登录.我想知道我对这个小文本有什么样的控制方式.我打算在几个不同的域上部署OpenID,但我更愿意,如果它们都可以工作,而不必单独配置特殊参数,例如秘密API密钥,什么不是.但是,我不确定这是否是OpenID的先决条件,即Google提供的联合登录API.
我的大脑似乎是在自虐模式,所以在之后被淹死这个,这个和这个,它想勾搭C#一些DIY.
我想出了下面,我不认为是Y组合子,但它确实似乎设法使非递归函数的递归,没有提及自己:
Func<Func<dynamic, dynamic>, Func<dynamic, dynamic>> Y = x => x(x);
Run Code Online (Sandbox Code Playgroud)
所以给出这些:
Func<dynamic, Func<dynamic, dynamic>> fact =
self => n => n == 0 ? 1 : n * self(self)(n - 1);
Func<dynamic, Func<dynamic, dynamic>> fib =
self => n => n < 2 ? n : self(self)(n-1) + self(self)(n-2);
Run Code Online (Sandbox Code Playgroud)
我们可以生成这些:
Func<dynamic, dynamic> Fact = Y(fact);
Func<dynamic, dynamic> Fib = Y(fib);
Enumerable.Range(0, 10)
.ToList()
.ForEach(i => Console.WriteLine("Fact({0})={1}", i, Fact(i)));
Enumerable.Range(0, …Run Code Online (Sandbox Code Playgroud) c# ×5
.net ×2
f# ×2
.net-4.5 ×1
algorithm ×1
coding-style ×1
dynamic ×1
exception ×1
generics ×1
google-apps ×1
openid ×1
permutation ×1
svn ×1
y-combinator ×1