在什么情况下会想要使用
public async Task AsyncMethod(int num)
Run Code Online (Sandbox Code Playgroud)
代替
public async void AsyncMethod(int num)
Run Code Online (Sandbox Code Playgroud)
我能想到的唯一情况是,您是否需要能够跟踪其进度的任务.
此外,在以下方法中,async和await关键字是否不必要?
public static async void AsyncMethod2(int num)
{
await Task.Factory.StartNew(() => Thread.Sleep(num));
}
Run Code Online (Sandbox Code Playgroud) 假设我有一个包含任意类型任意数量属性的类
public class Test
{
public string A {get;set;}
public object B {get;set;}
public int C {get;set;}
public CustomClass D {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
我希望这个类中的所有对象都有"错误"和"警告"的概念.例如,基于另一个类中的某些条件,我可能想要在属性A上设置警告,然后在GUI中显示该信息.GUI不是我关注的问题; 而我应该如何设置此警告?我希望能够做到这样的事情:
对于类中的每个属性,添加一个'Warning'和'Error'属性,以便我可以做..
Test t = new Test();
t.A.Warning = "This is a warning that the GUI will know to display in yellow".
t.B.Error = null;
Run Code Online (Sandbox Code Playgroud)
这样做的最佳方法是什么?如果我可以为类的每个属性添加一个自定义属性,这将添加这些附加属性并允许我以明确的方式访问它们,这将是很好的.
我已经看到了将Dictionary添加到父类(Test)的解决方案,然后传入与属性名称匹配的字符串,或者使用反射来获取属性名称并将其传递给我,但我更喜欢更清洁的东西.
我正在为我们的应用程序实现观察者模式 - 目前正在使用RX Framework.
我目前有一个看起来像这样的例子:
Observable.FromEventPattern<PropertyChangedEventArgs>(Instance.Address, "PropertyChanged")
.Where(e => e.EventArgs.PropertyName == "City")
.ObserveOn(Scheduler.ThreadPool)
.Subscribe(search => OnNewSearch(search.EventArgs));
Run Code Online (Sandbox Code Playgroud)
(我有一个类似的"PropertyChanging")
EventArgs不会给我太多.我想要的是EventArgs的扩展,它使我能够查看先前和新值,以及在"更改"侦听器中标记事件的能力,以便更改实际上不会持续存在.如何才能做到这一点?谢谢.
这是保证线程安全/不会产生意外结果吗?
Interlocked.Increment(ref _arr[i]);
Run Code Online (Sandbox Code Playgroud)
我的直觉告诉我这不是,即读取_arr [i]中的值并不能保证在实际递增时是"原子的".
如果我认为这是错误的,我该如何解决这个问题呢?谢谢.
我试图了解Hashtables如何在C#中工作.我阅读了MSDN文章,我理解C#Hashtables使用'rehashing'进行冲突,即如果我尝试将键/值对插入哈希表,如果使用HashFunction H1导致冲突,那么它将尝试HashFunction H2,H3等,直到找不到碰撞.
MSDN报价:
Hashtable类使用称为rehasing的不同技术.(有些消息来源称重新散列为双重散列.)
Rehashing的工作方式如下:有一组哈希不同的函数,H1 ... Hn,当从哈希表中插入或检索项时,最初使用H1哈希函数.如果这会导致碰撞,则尝试使用H2,如果需要,则转到Hn.上一节仅显示了一个哈希函数,即初始哈希函数(H1).其他散列函数与此函数非常相似,仅通过乘法因子进行区分.通常,散列函数Hk定义为:
Hk(key)= [GetHash(key)+ k*(1 +(((GetHash(key)>> 5)+ 1)%(hashsize - 1)))]%hashsize
但是,从MSDN site1获取示例:
private static Hashtable employees = new Hashtable();
public static void Main()
{
// Add some values to the Hashtable, indexed by a string key
employees.Add("111-22-3333", "Scott");
employees.Add("222-33-4444", "Sam");
}
Run Code Online (Sandbox Code Playgroud)
假设添加第二个键将导致冲突,因此必须使用H2.但是,当我打电话给员工["222-33-4444"]时,哈希表如何知道使用H2?有没有单独的映射?谢谢.
我已经定义了以下任务
var t = Task.Factory.StartNew(
() => LongRunningMethod( cancellationToken ),
cancellationToken
);
t.ContinueWith(
Callback,
cancellationToken,
TaskContinuationOptions.None,
TaskScheduler.FromCurrentSynchronizationContext()
);
Run Code Online (Sandbox Code Playgroud)
在里面LongRunningMethod,我检查取消令牌是否有请求取消,如果是,我从方法返回.那很好用.
但是,在此方案中不会调用Callback.回调不被调用,如果我替换上面的第二行
t.ContinueWith(
x => Callback( x, cancellationToken ),
TaskScheduler.FromCurrentSynchronizationContext()
);
Run Code Online (Sandbox Code Playgroud)
在这种情况下,任务仍然认为它已完成.
为什么第一次通话不起作用?我的印象TaskContinuationOptions.None是,无论线程的状态如何,都会调用回调.
我通过调用取消任务:
_cancellationTokenSource.Cancel();
Run Code Online (Sandbox Code Playgroud)
在一个有点相关的说明,不得不传递取消令牌似乎是任务库的主要设计缺陷.
我试图使用.net Observable类实现一个简单的Observer模式.我的代码看起来像这样:
Observable.FromEventPattern<PropertyChangedEventArgs>(
Instance.User,
"PropertyChanged")
.Where(e => e.EventArgs.PropertyName == "FirstName")
.ObserveOn(Scheduler.ThreadPool)
.Subscribe(search => OnFirstNameChanged(search.EventArgs));
Observable.FromEventPattern<PropertyChangedEventArgs>(
Instance.User,
"PropertyChanged")
.Where(e => e.EventArgs.PropertyName == "LastName")
.ObserveOn(Scheduler.ThreadPool)
.Subscribe(search => OnLastNameChanged(search.EventArgs));
Run Code Online (Sandbox Code Playgroud)
我希望观察者在后台线程上运行,但是我希望它们都在相同的后台线程上运行(对于我们真正的实现,将每个侦听器放在不同的线程上会非常复杂).
即我希望所有的OnXXXChanged逻辑都在UI线程以外的线程上执行,但是Observing我想确保它们在同一个线程上以正确的顺序运行,而不是在整个线程池上运行.
如何修改上述内容?
另外,在某种程度上相关的说明,是否有任何好的示例代码示例使用Observable该类来实现此模式?
如果在后台线程上运行以下代码,我怎么能在主线程上'ContinueWith'?
var task = Task.Factory.StartNew(() => Whatever());
task.ContinueWith(NeedThisMethodToBeOnUiThread), TaskScheduler.FromCurrentSynchronizationContext())
Run Code Online (Sandbox Code Playgroud)
以上操作无效,因为当前同步上下文已经是后台线程.
我只是想异步检索数据,并在检索数据后,在UI(Winforms)中显示它.
使用.net 4.0,有两种方法可以实现这个(我知道还有更多,但我使用这两种方式):
var task = Task.Factory.StartNew(() => RetrieveData());
task.ContinueWith(x => SetDataInUi(x.Result), TaskScheduler.FromCurrentSynchronizationContext());
Run Code Online (Sandbox Code Playgroud)
要么
var obs = Observable.Start(() => RetrieveData());
obs.ObserveOn(SynchronizationContext.Current).Subscribe(x => SetDataInUi(x));
Run Code Online (Sandbox Code Playgroud)
据我所知,这些都会做同样的事情.是否有理由选择其中一个?
如何修改某些WPF控件(即组合框,文本框等)以在控件的后台有一个进度条(我可以根据需要启用和禁用).我不需要它来实际显示准确的进度,而是我只需要指示此控件正在等待某些事情完成.控件内的旋转图标也可以.
我似乎有一些答案可以解决另一个控制问题和设置透明度等问题,但我更希望找到更好的解决方案.
谢谢!
c# ×7
c#-4.0 ×5
.net ×4
.net-4.0 ×2
asynchronous ×2
.net-4.5 ×1
attributes ×1
hashtable ×1
observable ×1
progress-bar ×1
task ×1
wpf ×1