我有一个.NET SignalR客户端,代码如下:
IHubProxy proxy = objConnection.CreateHubProxy("stockTicker");
objConnection.Start().Wait();
Console.WriteLine(objConnection.ConnectionId);
Run Code Online (Sandbox Code Playgroud)
问题是客户端在30秒后挂起,需要重新连接.解决方案是更改Wait方法:
IHubProxy proxy = objConnection.CreateHubProxy("stockTicker");
await objConnection.Start();
Console.WriteLine(objConnection.ConnectionId);
Run Code Online (Sandbox Code Playgroud)
我看不出人们在SignalR或其他一些情况下呼叫"等待"的原因.有没有办法让被调用的代码(Start()在这个例子中)知道它被调用的方式?
这个想法是,对于不应该使用的用例,Waited()可以抛出异常.
我最近发布了另一个问题,关于如何处理数据库中的项目列表,如果进程失败,则重试3次.
问题可以在这里找到:C#处理循环中的大项目列表,如果失败则重试
我对这个问题的答案做了一些修改,这里是代码:
我有一个继承ApiController类的抽象类,我的所有Web Api控制器都继承了ApiBaseController:
在ApiBaseController我已经定义了使用Repository模式的UnitOfWork以便CRUD SQL数据库.UnitOfWork和存储库模式工作正常,我测试了它,我没有遇到任何问题.
public abstract class ApiBaseController : ApiController
{
protected UnitOfWork Uow { get; set; }
protected override void Dispose(bool disposing)
{
if (Uow != null && Uow is IDisposable)
{
((IDisposable)Uow).Dispose();
Uow = null;
}
base.Dispose(disposing);
}
}
Run Code Online (Sandbox Code Playgroud)
在这里,我有一个JobController继承ApiBaseController继承的东西ApiController,使其成为Web Api控制器.
该控制器有一个端点api/endpoint/sendrequests,当被调用时,它将Jobs从数据库中获取所有数据并以10个批次处理它们.
该方法ProcessTaskAsync将处理从数据库检索的每个单独任务,如果它失败,那么它将尝试再处理2次,直到该任务被忽略.
除了在ProcessTaskAsync处理任务之后我尝试使用UnitOfWork将任务的结果保存到数据库之外,一切都工作得很好await Uow.Results.AddAsync(result);.在这里它失败了!问题是Uow对象是null,我不明白为什么.我的想法是因为任务是异步处理的,控制器执行结束意味着控制器被处理,因此UnitOfWork.
知道为什么Uow是null并且我该如何解决这个问题?
[AllowAnonymous]
[RoutePrefix("api/endpoint")] …Run Code Online (Sandbox Code Playgroud) 经过Stack Overflow上的大量帖子后,我想我能够提出一个线程安全版本的List,这肯定不符合Concurrent集合的水平,因为它使用了ReaderWriterLockSlim,但在我的理解中,它与简单的锁定版本相比,它可以按预期工作并具有更好的性能.您可能认为的任何内容都可以在当前的实现中得到改进.它仍然没有实现List的所有功能,因为我刚刚处理了IList
免责声明 - 我从Stack Overflow中得到了一些想法,所以它肯定包含来自不同帖子的点点滴滴
修改 - 修改代码以处理某些情况,这些情景在上次通信中发布,如:
if(list.count > 0)
return list[0]
Run Code Online (Sandbox Code Playgroud)
作为偏离主题,没有理由将此标记为暂停
线程安全实现
using System.Collections.Generic;
using System.Threading;
/// <summary>
/// Thread safe version of the List using
/// </summary>
/// <typeparam name="T"></typeparam>
public class ThreadSafeListWithRWLock<T> : IList<T>
{
private List<T> internalList;
private readonly ReaderWriterLockSlim rwLockList;
public ThreadSafeListWithRWLock()
{
internalList = new List<T>();
rwLockList = new ReaderWriterLockSlim();
}
// Other Elements of IList implementation
public IEnumerator<T> GetEnumerator()
{
return Clone().GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return Clone().GetEnumerator();
}
public …Run Code Online (Sandbox Code Playgroud) .net c# parallel-processing multithreading task-parallel-library
我有一些有时可以工作的异步代码,有时却没有.使用此代码,始终会创建文件,但有时它是空的(我总是发送包含内容的文件):
[HttpPost]
[Route("api/inventory/sendxml/{userId}/{pwd}/{filename}")]
public async void SendInventoryXML(String userId, String pwd, String fileName)
{
Task task = Request.Content.ReadAsStreamAsync().ContinueWith(t =>
{
var stream = t.Result;
using (FileStream fileStream = File.Create(String.Format(@"C:\HDP\{0}.xml", fileName), (int)stream.Length))
{
byte[] bytesInStream = new byte[stream.Length];
stream.Read(bytesInStream, 0, (int)bytesInStream.Length);
fileStream.Write(bytesInStream, 0, bytesInStream.Length);
}
});
}
Run Code Online (Sandbox Code Playgroud)
那么,我是否应该取消同步这个随机工作的代码,如果是的话,如何(如果没有不同步的变幻无常的事情(假设是导致这种随机行为的问题)将会完成同样的事情)?
我有以下代码调用2个异步方法并等待结果:
private Task FirstTaskAsync() {
...
}
private Task SecondTaskAsync() {
...
}
private async void Caller() {
await FirstTaskAsync();
await SecondTaskAsync();
}
Run Code Online (Sandbox Code Playgroud)
问题是它现在执行并顺序等待每个任务.我想将其更改为Task.WaitAll().这是我的改变:
private async void Caller() {
var first = FirstTaskAsync();
var second = SecondTaskAsync();
Task.WaitAll(first, second);
}
Run Code Online (Sandbox Code Playgroud)
但是当我测试它时,Task.WaitAll()永远不会返回.你能告诉我缺少什么吗?
我正在开发一个C#控制台应用程序,它将负责运行一系列任务.其基本结构如下:
var tasks = workItems.Select(x => Task.Factory.StartNew(() =>
{
DoSomeWork(x);
})).ToArray();
Task.WaitAll(tasks);
Run Code Online (Sandbox Code Playgroud)
问题是DoSomeWork()是一个异步方法,等待另一个任务的结果,它还需要等待对Facebook API的调用. http://facebooksdk.net/docs/reference/SDK/Facebook.FacebookClient.html#GetTaskAsync(string)
public async void DoSomeWork(WorkItem item)
{
var results = await GetWorkData();
}
public async Task<List<WorkData>> GetWorkData()
{
var fbClient = new FacebookClient();
var task = fbClient.GetTaskAsync("something");
var fbResults = await task;
};
Run Code Online (Sandbox Code Playgroud)
我以为我能够通过调用Task.WaitAll()来支持这种嵌套任务的概念,但父任务的执行几乎立即完成.在应用程序的末尾放置一个Console.ReadLine()以防止它提前执行,这表明结果确实会在稍后从Facebook返回.
我是否遗漏了一些明显的东西,或者是否有更好的方法来阻止我的任务集合,这将允许这种情况?
ConcurrentDictionary有public bool TryGetValue(TKey key, out TValue value)检查特定键是否在字典中,但我真的不需要out TValue value.只想知道密钥是否在字典中.
从技术上讲,我可以使用Item属性,但必须将其包含在try/catch子句中.
Parallel.ForEach继续运行,我的程序没有结束.我无法追踪第一次迭代后的位置.我的猜测是获得死锁并继续进行上下文切换.
private void ReadInputFile()
{
var collection = new ConcurrentBag<PropertyRecord>();
var lines = System.IO.File.ReadLines(InputFileName);
int i = 0;
int RecordsCount = lines.Count();
Parallel.ForEach(lines, line =>
{
if (string.IsNullOrWhiteSpace(line))
{
return;
}
var tokens = line.Split(',');
var postalCode = tokens[0];
var country = tokens.Length > 1 ? tokens[1] : "england";
SetLabelNotifyTwoText(
string.Format(
"Reading PostCode {0} out of {1}"
i,
lines.Length));
var tempRecord = GetAllAddesses(postalCode, country);
if (tempRecord != null)
{
foreach (PropertyRecord r in tempRecord)
{
collection.Add(r);
}
}
}); …Run Code Online (Sandbox Code Playgroud) 好吧,就我从线程中读到的而言,这是不可能的,但在我的情况下肯定会发生.
取决于我开始执行多少后台任务,即使它们与ui线程有0关系,也肯定会影响我的gui响应
所以我的问题是,是否有人知道其他线程如何使ui变得反应迟钝?
我100%确定这些非ui线程导致其缓慢,因为它发生,即使我禁用所有gui更新事件.它肯定受我的案例中有多少个线程(抓取网址任务和处理这些抓取的页面任务)的影响
这是我的ui线程以及我如何开始后台任务:
InitializeComponent();
this.DataContext = this;
ThreadPool.SetMaxThreads(10000, 10000);
ThreadPool.SetMinThreads(10000, 10000);
PublicVariables.initPublicVariables();
PublicStaticFunctions.func_initLists();
PublicSettings.func_init_Settings_Messages();
Task.Factory.StartNew(() =>
{
CheckCrawlURLs.func_StartCrawlingWaitingUrls();
AddUrlsToDB.func_StartUrlAddProcess();
LoadCrawlingUrlsFromDatabase.func_StartLoadingUrlsFromDB();
GlobalStats.startUpdatingGlobalStatValues();
PagesProcessor.func_StartProcessingWaitingPages();
}, CancellationToken.None,
TaskCreationOptions.LongRunning,
TaskScheduler.Default);
AppDomain currentDomain = AppDomain.CurrentDomain;
Application.Current.DispatcherUnhandledException +=
new DispatcherUnhandledExceptionEventHandler(CloseCrashHandlers.AppDispatcherUnhandledException);
currentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CloseCrashHandlers.CrashCloseHandler);
Closing += new CancelEventHandler(CloseCrashHandlers.CloseHander);
set_Buttons_Status();
_timer = new Timer(updateGlobalStatistics,
null,
PublicSettings.irTimers_Delayed_Start_MiliSeconds,
PublicSettings.ir_RefreshUI_MS);
WebConnectionStats.Init();
Run Code Online (Sandbox Code Playgroud) 我正在使用一个看起来像这样的动作块:
ActionBlock<Tuple<string,byte[],string>> ab =
new ActionBlock<Tuple<string,string,string>>(item => {
service.DoSomeAction(item.Item1, item.Item2, item.Item3);
},
new ExecutionDataflowBlockOptions {
MaxDegreeOfParallelism = 2
});
foreach(var item in Items) {
ab.Post(new Tuple<string,string,string>(item.a, item.b, item.c));
}
ab.Complete();
ab.Completion.Wait();
Run Code Online (Sandbox Code Playgroud)
我的问题是,service.DoSomeAction()由于网络负载可能会失败,我想知道ActionBlock是否有一个机制来重新启动任务.
我当然可以在该调用周围添加一个try/catch块,并在重新抛出异常之前让catch块等待/重试几次.我要找的是ab.Post()用相同的参数调用.我的问题是我已经打电话了ab.Complete().是否可以在不调用的情况下等待ActionBlock ab.Complete().是否有更好的工具可以用于工作?