首页 \ 问答 \ SAS是否有像Java这样的并发框架(Does SAS have a concurrency framework like Java)

SAS是否有像Java这样的并发框架(Does SAS have a concurrency framework like Java)

在Java中,您有一个并发框架,开发人员可以使用它来并行提交多个任务,其中每个任务都在自己的线程中运行。

SAS中是否存在类似的并发框架,开发人员可以在不同的线程中提交并行作业或程序?


In Java,you have a concurrency framework that the developer can use to submit multiple tasks in parallel where each task runs in its own thread.

Does a similar concurrency framework exist in SAS where developer can submit parallel jobs or programs in different threads?


原文:https://stackoverflow.com/questions/32303289
更新时间:2023-10-09 22:10

最满意答案

这是问题: answer = MyQuestion(question).Result;

Task上使用Result意味着“得到结果,但如果它还不可用,请等待 - 即阻止线程等待结果”。

由于MyQuestion等待来自TaskCompletionSourceTask应该完成QuestionManager或其他UI代码,而QuestionManager (通过Result )正在等待MyQuestion完成,所以你有一个死锁! QuestionManager阻止了UI线程,因此tcs无法通过下一行或任何其他运行的UI代码接收结果。

Result更改为await它,这将消失。 我不确定其余的逻辑是否会保持在一起,但这就是为什么在运行您发布的代码时UI会锁定的答案。


至于如何解决这个问题:这些都不需要任何异步等待。 使用异步会掩盖您实际想要编写的代码,并且您正在使用async void方法,这几乎总是一个坏主意

我要做的是有一个具有问题和答案属性的类,保留所有剩余问题和答案的列表,并且每当提交新答案时始终对该列表中的第一项起作用,以查看答案是否为正确 - 您将知道是否显示“错误答案”并让他们再次尝试或是否进入下一个问题。

例如:

class QuestionAndAnswer {
    public string Question { get; set; } 
    public string Answer { get; set; }
}

private List<QuestionAndAnswer> _currentQuestions; // create this list when loading everything

private int _currentQuestionIndex = 0; // points to which element/index in the list contains the question shown on screen

// call this once after you have loaded _currentQuestions with your data
public void ShowCurrentQuestion() { 
    var currQuestion = _currentQuestion[_currentQuestionIndex];
    computerQuestionLabel.Text = currQuestion.Question;
    answerTextBox.Text = "";
}

// call this from whichever event handler means that the user has
// submitted an answer - an Answer button's Click event, maybe
// answerTextBox's KeyPress event or something else.
public void CheckForAnswer() {
    var currentAnswer = answerTextBox.Text;
    var currQuestion = _currentQuestion[_currentQuestionIndex];
    if (currQuestion.Answer == currentAnswer) { // correct
        var nextQuestionIndex = _currentQuestionIndex + 1;
        if (nextQuestionIndex == _currentQuestion.Count) { 
            // all questions answered! do the appropriate thing
        } else {
            // still questions left, show the next one
            _currentQuestionIndex = nextQuestionIndex;
            ShowCurrentQuestion();
        }
    } else {
        // wrong answer; the question that needs to be shown is 
        // already shown, you can handle "stop" or other things here
    }
}

这里有一个自然事件,意思是“有人刚刚提交了一个新答案”,您可以将其用作漏斗点。 没有必要编写等待新答案的代码。 通过编写使事件响应用户事件而发生的代码,您已经实际上异步处理(做你的事情,等待用户做某事,做更多事情),这只是你没有使用async / await / Task s或显式编写异步代码来完成它。


This is the issue: answer = MyQuestion(question).Result;.

Using Result on a Task means "get me the result, but if it's not yet available, wait - ie block the thread waiting for the result of this".

Since MyQuestion waits for the Task from a TaskCompletionSource that QuestionManager or other UI code is supposed to complete, and QuestionManager (through Result) is waiting for MyQuestion to finish, you have a deadlock! QuestionManager is blocking the UI thread, so tcs can't receive a result either through the next line or through any other UI code running.

Change Result to awaiting it, and this will go away. I am not certain that the rest of the logic will hold together, but this is the answer to why the UI locks up when you run the code you posted.


As for how to solve this: none of this actually requires any asynchronous waiting. Using asynchrony obscures the code you actually want to write, and you're using async void methods which is nearly always a bad idea.

What I would do is have a class with properties for a question and an answer, keep a list of all remaining questions-and-answers and always work against the first item in that list whenever a new answer is submitted to see if the answer is correct - you'll know whether to show "wrong answer" and have them try again or whether to advance to the next question.

For example:

class QuestionAndAnswer {
    public string Question { get; set; } 
    public string Answer { get; set; }
}

private List<QuestionAndAnswer> _currentQuestions; // create this list when loading everything

private int _currentQuestionIndex = 0; // points to which element/index in the list contains the question shown on screen

// call this once after you have loaded _currentQuestions with your data
public void ShowCurrentQuestion() { 
    var currQuestion = _currentQuestion[_currentQuestionIndex];
    computerQuestionLabel.Text = currQuestion.Question;
    answerTextBox.Text = "";
}

// call this from whichever event handler means that the user has
// submitted an answer - an Answer button's Click event, maybe
// answerTextBox's KeyPress event or something else.
public void CheckForAnswer() {
    var currentAnswer = answerTextBox.Text;
    var currQuestion = _currentQuestion[_currentQuestionIndex];
    if (currQuestion.Answer == currentAnswer) { // correct
        var nextQuestionIndex = _currentQuestionIndex + 1;
        if (nextQuestionIndex == _currentQuestion.Count) { 
            // all questions answered! do the appropriate thing
        } else {
            // still questions left, show the next one
            _currentQuestionIndex = nextQuestionIndex;
            ShowCurrentQuestion();
        }
    } else {
        // wrong answer; the question that needs to be shown is 
        // already shown, you can handle "stop" or other things here
    }
}

There's a natural event here meaning "someone just submitted a new answer", and you can use that as a funnel point. There's no need to write code that waits for new answers. By writing code that makes things happen in response to user events, you are already in effect doing things asynchronously (do your stuff, wait for the user to do something, do even more stuff), it's just that you're not using async/await/Tasks or writing explicitly asynchronous code to do it.

相关问答

更多
  • 在C#和C ++之间异步通信与C#应用程序的两个部分之间异步通信没有什么不同 - 您最终在最后调用一个不同的函数 - 也就是说,C#的delegate类型将变成C ++最终提供的函数指针.NET JIT。 这被称为反向P / Invoke,并允许非托管C ++调用.NET代码。 Communicating asynchronously between C# and C++ is no different to communicating asynchronously between two parts of ...
  • 数据库查询和写入文件都是I / O绑定操作,因此它们非常适合async和await 。 首先,您将定义KuliMon.Export的异步版本: async Task ExportAsync() { var data = await myQuery.ToListAsync(); await myStream.WriteAsync(...); return results; } 例如,您可以使用Entity Framework 6进行异步查询支持 。 然后你可以从你的UI中调用 ...
  • 正确,你有一个经典的异步阻止另一个异步的情况。 您应该在等待ScannedCode.AddAsync()时将ConfigureAwait设置为false; await ScannedCode.AddAsync().ConfigureAwait(false); 这使它在线程池线程而不是ASP.NET请求上下文上恢复。 您可以阅读以下文章http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html ,它可以很好地解释这一点以及使用异步 ...
  • 你可能想写inventory.ItemID = 1; 而不是Inventory.ItemID = 1; 。 也就是说,如果你想设置player.GetComponent();的结果的ItemId player.GetComponent(); 到1。 您正尝试在类Inventory上调用方法而不是在对象inventory上调用方法,并且如果方法不是静态的,则无法理解。 You probably want to write inventory.ItemID = 1; ...
  • 如果我们只使用单个套接字,那么将状态传递给BeginReceive方法有什么意义呢? 是否要避免使用类字段? 这样做似乎没什么意义,但也许我错过了一些东西。 你是对的,如果你没有使用状态,那么你必须使用一个成员。 但这不是一个状态变量本地。 本地事物越多,当您在代码的其他部分进行更改时,它们破坏的可能性就越小。 将它与普通方法调用进行比较。 为什么我们不将参数设置为成员,然后调用所有函数而不使用任何参数? 它会工作......但阅读代码会很糟糕。 通过将范围尽可能保持在本地,可以使设计更易于理解和修改。 改 ...
  • 这是问题: answer = MyQuestion(question).Result; 。 在Task上使用Result意味着“得到结果,但如果它还不可用,请等待 - 即阻止线程等待结果”。 由于MyQuestion等待来自TaskCompletionSource的Task应该完成QuestionManager或其他UI代码,而QuestionManager (通过Result )正在等待MyQuestion完成,所以你有一个死锁! QuestionManager阻止了UI线程,因此tcs无法通过下一行或任 ...
  • 你在哪里调用DisplayText cSocket.BeginSend怎么样? 显然能够使用BeginSend ,您需要将文本放入缓冲区。 有多种方法可以有效地完成它,但它超出了这个答案的范围。 但是如果您期望某种结构化数据(例如由换行符分隔的字符串),那么最好使用StreamReader.ReadLine 。 如果结构更复杂,那么您需要自己从缓冲区进行解析。 所以你需要从缓冲区中消耗一个字符,看看你是否有足够的数据,如果没有消耗,直到缓冲区为空。 当缓冲区为空时,您需要通过调用BeginReceive再次 ...
  • 显然workSheet.SaveAs()做了自己的路径验证和修复。 所以你(正当地)因使用无效格式而受到惩罚。 这种格式通常被接受,但“通常”与“始终”不同。 Apparently workSheet.SaveAs() does its own validation and fix-up of the path. So you are (rightfully) being punished for using an invalid format. That format is usually accepte ...
  • 不,这是一个普遍的错误,并不是特定于异步代码。 在你的情况下,你可能更容易字节,因为你永远不会有[DllImport]背后的机器让你摆脱困境。 我会解释为什么会出错,也许这会有所帮助。 总是需要一个回调方法的委托声明,这就是CLR现在知道如何调用该方法。 您经常使用delegate关键字明确声明它,如果非托管代码是32位,您可能需要应用[UnmanagedFunctionPointer]属性,并假设该函数是用C或C ++编写的。 声明很重要,这就是CLR如何知道您从本机代码传递的参数如何转换为其托管等效项。 ...
  • select和poll有两个问题: 它们通常以单线程方式使用。 由于这个原因,它们无法扩展。 它们需要通过执行轮询的中心位置调度所有IO。 能够只指定在完成时神奇地调用的回调要好得多。 这会自动扩展,并且没有需要调度的中心位置。 .NET中的异步IO完全没有麻烦。 它只是有效(高效)。 Windows上的Async IO是无线程的。 当IO正在运行时,没有一个线程忙于提供它。 .NET中的所有异步IO都使用操作系统支持的真正异步IO。 这意味着重叠的IO或完成端口。 查看async / await,它也可以 ...

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。